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
fb5b651d
Commit
fb5b651d
authored
Mar 13, 2018
by
Leonardo Aramaki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop-2.x' into new/spotlight
parents
31ff5935
676b84c0
Changes
55
Hide whitespace changes
Inline
Side-by-side
Showing
55 changed files
with
736 additions
and
226 deletions
+736
-226
build.gradle
app/build.gradle
+1
-0
AudioAttachmentViewHolder.kt
...ket/android/chatroom/adapter/AudioAttachmentViewHolder.kt
+5
-2
BaseViewHolder.kt
...va/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt
+42
-3
ChatRoomAdapter.kt
...a/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
+32
-7
ImageAttachmentViewHolder.kt
...ket/android/chatroom/adapter/ImageAttachmentViewHolder.kt
+5
-2
MessageReactionsAdapter.kt
...ocket/android/chatroom/adapter/MessageReactionsAdapter.kt
+137
-0
MessageViewHolder.kt
...chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
+4
-2
UrlPreviewViewHolder.kt
...t/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
+5
-2
VideoAttachmentViewHolder.kt
...ket/android/chatroom/adapter/VideoAttachmentViewHolder.kt
+5
-2
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+19
-2
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+1
-0
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+25
-7
AudioAttachmentViewModel.kt
...et/android/chatroom/viewmodel/AudioAttachmentViewModel.kt
+4
-2
BaseViewModel.kt
...a/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
+2
-0
ImageAttachmentViewModel.kt
...et/android/chatroom/viewmodel/ImageAttachmentViewModel.kt
+3
-1
MessageViewModel.kt
...hat/rocket/android/chatroom/viewmodel/MessageViewModel.kt
+2
-0
ReactionViewModel.kt
...at/rocket/android/chatroom/viewmodel/ReactionViewModel.kt
+9
-0
UrlPreviewViewModel.kt
.../rocket/android/chatroom/viewmodel/UrlPreviewViewModel.kt
+9
-7
VideoAttachmentViewModel.kt
...et/android/chatroom/viewmodel/VideoAttachmentViewModel.kt
+3
-1
ViewModelMapper.kt
...chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
+27
-5
ChatRoomsFragmentModule.kt
...at/rocket/android/chatrooms/di/ChatRoomsFragmentModule.kt
+0
-7
ChatRoomsModule.kt
.../java/chat/rocket/android/chatrooms/di/ChatRoomsModule.kt
+0
-16
ChatRoomsNavigator.kt
...cket/android/chatrooms/presentation/ChatRoomsNavigator.kt
+0
-20
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+2
-1
LocalComponent.kt
...rc/main/java/chat/rocket/android/dagger/LocalComponent.kt
+27
-0
ActivityBuilder.kt
...java/chat/rocket/android/dagger/module/ActivityBuilder.kt
+0
-4
LocalModule.kt
...ain/java/chat/rocket/android/dagger/module/LocalModule.kt
+24
-0
MainActivityModule.kt
...in/java/chat/rocket/android/main/di/MainActivityModule.kt
+0
-23
MainActivityProvider.kt
.../java/chat/rocket/android/main/di/MainActivityProvider.kt
+0
-12
MainModule.kt
app/src/main/java/chat/rocket/android/main/di/MainModule.kt
+13
-0
MainNavigator.kt
...va/chat/rocket/android/main/presentation/MainNavigator.kt
+12
-0
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+18
-11
MainActivity.kt
...src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+6
-7
ProfileFragmentModule.kt
...a/chat/rocket/android/profile/di/ProfileFragmentModule.kt
+0
-7
CategoryPagerAdapter.kt
.../chat/rocket/android/widget/emoji/CategoryPagerAdapter.kt
+4
-4
EmojiKeyboardListener.kt
...chat/rocket/android/widget/emoji/EmojiKeyboardListener.kt
+19
-0
EmojiKeyboardPopup.kt
...va/chat/rocket/android/widget/emoji/EmojiKeyboardPopup.kt
+8
-29
EmojiListenerAdapter.kt
.../chat/rocket/android/widget/emoji/EmojiListenerAdapter.kt
+12
-0
EmojiPickerPopup.kt
...java/chat/rocket/android/widget/emoji/EmojiPickerPopup.kt
+61
-0
EmojiReactionListener.kt
...chat/rocket/android/widget/emoji/EmojiReactionListener.kt
+19
-0
ic_add_reaction.xml
app/src/main/res/drawable/ic_add_reaction.xml
+25
-0
rounded_background.xml
app/src/main/res/drawable/rounded_background.xml
+9
-0
emoji_keyboard.xml
app/src/main/res/layout/emoji_keyboard.xml
+7
-24
emoji_picker.xml
app/src/main/res/layout/emoji_picker.xml
+27
-0
item_add_reaction.xml
app/src/main/res/layout/item_add_reaction.xml
+11
-0
item_message.xml
app/src/main/res/layout/item_message.xml
+8
-1
item_reaction.xml
app/src/main/res/layout/item_reaction.xml
+42
-0
layout_reactions.xml
app/src/main/res/layout/layout_reactions.xml
+5
-0
message_attachment.xml
app/src/main/res/layout/message_attachment.xml
+7
-2
message_url_preview.xml
app/src/main/res/layout/message_url_preview.xml
+18
-12
message_actions.xml
app/src/main/res/menu/message_actions.xml
+5
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+2
-1
dimens.xml
app/src/main/res/values/dimens.xml
+2
-0
strings.xml
app/src/main/res/values/strings.xml
+1
-0
dependencies.gradle
dependencies.gradle
+2
-0
No files found.
app/build.gradle
View file @
fb5b651d
...
...
@@ -59,6 +59,7 @@ dependencies {
implementation
libraries
.
design
implementation
libraries
.
constraintLayout
implementation
libraries
.
cardView
implementation
libraries
.
flexbox
implementation
libraries
.
androidKtx
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/AudioAttachmentViewHolder.kt
View file @
fb5b651d
...
...
@@ -4,10 +4,13 @@ import android.view.View
import
chat.rocket.android.chatroom.viewmodel.AudioAttachmentViewModel
import
chat.rocket.android.player.PlayerActivity
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.message_attachment.view.*
class
AudioAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
:
BaseViewHolder
<
AudioAttachmentViewModel
>(
itemView
,
listener
)
{
class
AudioAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
AudioAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt
View file @
fb5b651d
...
...
@@ -7,16 +7,22 @@ import chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.bottomsheet.BottomSheetMenu
import
chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.isSystemMessage
import
com.google.android.flexbox.FlexDirection
import
com.google.android.flexbox.FlexboxLayoutManager
import
ru.whalemare.sheetmenu.extension.inflate
import
ru.whalemare.sheetmenu.extension.toList
abstract
class
BaseViewHolder
<
T
:
BaseViewModel
<*>>(
itemView
:
View
,
private
val
listener
:
ActionsListener
itemView
:
View
,
private
val
listener
:
ActionsListener
,
var
reactionListener
:
EmojiReactionListener
?
=
null
)
:
RecyclerView
.
ViewHolder
(
itemView
),
MenuItem
.
OnMenuItemClickListener
{
MenuItem
.
OnMenuItemClickListener
{
var
data
:
T
?
=
null
init
{
...
...
@@ -26,6 +32,39 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
fun
bind
(
data
:
T
)
{
this
.
data
=
data
bindViews
(
data
)
bindReactions
()
}
private
fun
bindReactions
()
{
data
?.
let
{
val
recyclerView
=
itemView
.
findViewById
(
R
.
id
.
recycler_view_reactions
)
as
RecyclerView
val
adapter
:
MessageReactionsAdapter
if
(
recyclerView
.
adapter
==
null
)
{
adapter
=
MessageReactionsAdapter
()
}
else
{
adapter
=
recyclerView
.
adapter
as
MessageReactionsAdapter
adapter
.
clear
()
}
if
(
it
.
nextDownStreamMessage
==
null
)
{
adapter
.
listener
=
object
:
EmojiReactionListener
{
override
fun
onReactionTouched
(
messageId
:
String
,
emojiShortname
:
String
)
{
reactionListener
?.
onReactionTouched
(
messageId
,
emojiShortname
)
}
override
fun
onReactionAdded
(
messageId
:
String
,
emoji
:
Emoji
)
{
if
(!
adapter
.
contains
(
emoji
.
shortname
))
{
reactionListener
?.
onReactionAdded
(
messageId
,
emoji
)
}
}
}
val
context
=
itemView
.
context
val
manager
=
FlexboxLayoutManager
(
context
,
FlexDirection
.
ROW
)
recyclerView
.
layoutManager
=
manager
recyclerView
.
adapter
=
adapter
adapter
.
addReactions
(
it
.
reactions
.
filterNot
{
it
.
unicode
.
startsWith
(
":"
)
})
}
}
}
abstract
fun
bindViews
(
data
:
T
)
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
View file @
fb5b651d
...
...
@@ -7,6 +7,7 @@ import chat.rocket.android.R
import
chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import
chat.rocket.android.chatroom.viewmodel.*
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.isSystemMessage
import
timber.log.Timber
...
...
@@ -16,7 +17,8 @@ class ChatRoomAdapter(
private
val
roomType
:
String
,
private
val
roomName
:
String
,
private
val
presenter
:
ChatRoomPresenter
?,
private
val
enableActions
:
Boolean
=
true
private
val
enableActions
:
Boolean
=
true
,
private
val
reactionListener
:
EmojiReactionListener
?
=
null
)
:
RecyclerView
.
Adapter
<
BaseViewHolder
<*>>()
{
private
val
dataSet
=
ArrayList
<
BaseViewModel
<*>>()
...
...
@@ -29,23 +31,23 @@ class ChatRoomAdapter(
return
when
(
viewType
.
toViewType
())
{
BaseViewModel
.
ViewType
.
MESSAGE
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
item_message
)
MessageViewHolder
(
view
,
actionsListener
)
MessageViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
BaseViewModel
.
ViewType
.
IMAGE_ATTACHMENT
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
ImageAttachmentViewHolder
(
view
,
actionsListener
)
ImageAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
BaseViewModel
.
ViewType
.
AUDIO_ATTACHMENT
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
AudioAttachmentViewHolder
(
view
,
actionsListener
)
AudioAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
BaseViewModel
.
ViewType
.
VIDEO_ATTACHMENT
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
VideoAttachmentViewHolder
(
view
,
actionsListener
)
VideoAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
BaseViewModel
.
ViewType
.
URL_PREVIEW
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_url_preview
)
UrlPreviewViewHolder
(
view
,
actionsListener
)
UrlPreviewViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
else
->
{
throw
InvalidParameterException
(
"TODO - implement for ${viewType.toViewType()}"
)
...
...
@@ -62,6 +64,23 @@ class ChatRoomAdapter(
}
override
fun
onBindViewHolder
(
holder
:
BaseViewHolder
<
*
>,
position
:
Int
)
{
if
(
holder
!
is
MessageViewHolder
)
{
if
(
position
+
1
<
itemCount
)
{
val
messageAbove
=
dataSet
[
position
+
1
]
if
(
messageAbove
.
messageId
==
dataSet
[
position
].
messageId
)
{
messageAbove
.
nextDownStreamMessage
=
dataSet
[
position
]
}
}
}
else
{
if
(
position
==
0
)
{
dataSet
[
0
].
nextDownStreamMessage
=
null
}
else
if
(
position
-
1
>
0
)
{
if
(
dataSet
[
position
-
1
].
messageId
!=
dataSet
[
position
].
messageId
)
{
dataSet
[
position
].
nextDownStreamMessage
=
null
}
}
}
when
(
holder
)
{
is
MessageViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageViewModel
)
is
ImageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ImageAttachmentViewModel
)
...
...
@@ -97,12 +116,17 @@ class ChatRoomAdapter(
}
fun
updateItem
(
message
:
BaseViewModel
<
*
>)
{
va
l
index
=
dataSet
.
indexOfLast
{
it
.
messageId
==
message
.
messageId
}
va
r
index
=
dataSet
.
indexOfLast
{
it
.
messageId
==
message
.
messageId
}
val
indexOfFirst
=
dataSet
.
indexOfFirst
{
it
.
messageId
==
message
.
messageId
}
Timber
.
d
(
"index: $index"
)
if
(
index
>
-
1
)
{
message
.
nextDownStreamMessage
=
dataSet
[
index
].
nextDownStreamMessage
dataSet
[
index
]
=
message
notifyItemChanged
(
index
)
while
(
dataSet
[
index
].
nextDownStreamMessage
!=
null
)
{
dataSet
[
index
].
nextDownStreamMessage
!!
.
reactions
=
message
.
reactions
notifyItemChanged
(--
index
)
}
// Delete message only if current is a system message update, i.e.: Message Removed
if
(
message
.
message
.
isSystemMessage
()
&&
indexOfFirst
>
-
1
&&
indexOfFirst
!=
index
)
{
dataSet
.
removeAt
(
indexOfFirst
)
...
...
@@ -143,6 +167,7 @@ class ChatRoomAdapter(
}
}
}
R
.
id
.
action_menu_msg_react
->
presenter
?.
showReactions
(
id
)
else
->
TODO
(
"Not implemented"
)
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ImageAttachmentViewHolder.kt
View file @
fb5b651d
...
...
@@ -2,11 +2,14 @@ package chat.rocket.android.chatroom.adapter
import
android.view.View
import
chat.rocket.android.chatroom.viewmodel.ImageAttachmentViewModel
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
com.stfalcon.frescoimageviewer.ImageViewer
import
kotlinx.android.synthetic.main.message_attachment.view.*
class
ImageAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
:
BaseViewHolder
<
ImageAttachmentViewModel
>(
itemView
,
listener
)
{
class
ImageAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
ImageAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.chatroom.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.ImageView
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.viewmodel.ReactionViewModel
import
chat.rocket.android.dagger.DaggerLocalComponent
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.EmojiListenerAdapter
import
chat.rocket.android.widget.emoji.EmojiPickerPopup
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
java.util.concurrent.CopyOnWriteArrayList
import
javax.inject.Inject
class
MessageReactionsAdapter
:
RecyclerView
.
Adapter
<
RecyclerView
.
ViewHolder
>()
{
companion
object
{
private
const
val
REACTION_VIEW_TYPE
=
0
private
const
val
ADD_REACTION_VIEW_TYPE
=
1
}
private
val
reactions
=
CopyOnWriteArrayList
<
ReactionViewModel
>()
var
listener
:
EmojiReactionListener
?
=
null
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
RecyclerView
.
ViewHolder
{
val
inflater
=
LayoutInflater
.
from
(
parent
.
context
)
val
view
:
View
return
when
(
viewType
)
{
ADD_REACTION_VIEW_TYPE
->
{
view
=
inflater
.
inflate
(
R
.
layout
.
item_add_reaction
,
parent
,
false
)
AddReactionViewHolder
(
view
,
listener
)
}
else
->
{
view
=
inflater
.
inflate
(
R
.
layout
.
item_reaction
,
parent
,
false
)
SingleReactionViewHolder
(
view
,
listener
)
}
}
}
override
fun
onBindViewHolder
(
holder
:
RecyclerView
.
ViewHolder
,
position
:
Int
)
{
if
(
holder
is
SingleReactionViewHolder
)
{
holder
.
bind
(
reactions
[
position
])
}
else
{
holder
as
AddReactionViewHolder
holder
.
bind
(
reactions
[
0
].
messageId
)
}
}
override
fun
getItemCount
()
=
if
(
reactions
.
isEmpty
())
0
else
reactions
.
size
+
1
override
fun
getItemViewType
(
position
:
Int
):
Int
{
if
(
position
==
reactions
.
size
)
{
return
ADD_REACTION_VIEW_TYPE
}
return
REACTION_VIEW_TYPE
}
fun
addReactions
(
reactions
:
List
<
ReactionViewModel
>)
{
this
.
reactions
.
clear
()
this
.
reactions
.
addAllAbsent
(
reactions
)
notifyItemRangeInserted
(
0
,
reactions
.
size
)
}
fun
clear
()
{
val
oldSize
=
reactions
.
size
reactions
.
clear
()
notifyItemRangeRemoved
(
0
,
oldSize
)
}
fun
contains
(
reactionShortname
:
String
)
=
reactions
.
firstOrNull
{
it
.
shortname
==
reactionShortname
}
!=
null
class
SingleReactionViewHolder
(
view
:
View
,
private
val
listener
:
EmojiReactionListener
?)
:
RecyclerView
.
ViewHolder
(
view
),
View
.
OnClickListener
{
@Inject
lateinit
var
localRepository
:
LocalRepository
@Volatile
lateinit
var
reaction
:
ReactionViewModel
@Volatile
var
clickHandled
=
false
init
{
DaggerLocalComponent
.
builder
()
.
context
(
itemView
.
context
)
.
build
()
.
inject
(
this
)
}
fun
bind
(
reaction
:
ReactionViewModel
)
{
clickHandled
=
false
this
.
reaction
=
reaction
with
(
itemView
)
{
val
emojiTextView
=
findViewById
<
TextView
>(
R
.
id
.
text_emoji
)
val
countTextView
=
findViewById
<
TextView
>(
R
.
id
.
text_count
)
emojiTextView
.
text
=
reaction
.
unicode
countTextView
.
text
=
reaction
.
count
.
toString
()
val
myself
=
localRepository
.
get
(
LocalRepository
.
USERNAME_KEY
)
if
(
reaction
.
usernames
.
contains
(
myself
))
{
val
context
=
itemView
.
context
val
resources
=
context
.
resources
countTextView
.
setTextColor
(
resources
.
getColor
(
R
.
color
.
colorAccent
))
}
emojiTextView
.
setOnClickListener
(
this
@SingleReactionViewHolder
)
countTextView
.
setOnClickListener
(
this
@SingleReactionViewHolder
)
}
}
override
fun
onClick
(
v
:
View
?)
{
synchronized
(
this
)
{
if
(!
clickHandled
)
{
clickHandled
=
true
listener
?.
onReactionTouched
(
reaction
.
messageId
,
reaction
.
shortname
)
}
}
}
}
class
AddReactionViewHolder
(
view
:
View
,
private
val
listener
:
EmojiReactionListener
?)
:
RecyclerView
.
ViewHolder
(
view
)
{
fun
bind
(
messageId
:
String
)
{
itemView
as
ImageView
itemView
.
setOnClickListener
{
val
emojiPickerPopup
=
EmojiPickerPopup
(
itemView
.
context
)
emojiPickerPopup
.
listener
=
object
:
EmojiListenerAdapter
()
{
override
fun
onEmojiAdded
(
emoji
:
Emoji
)
{
listener
?.
onReactionAdded
(
messageId
,
emoji
)
}
}
emojiPickerPopup
.
show
()
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
View file @
fb5b651d
...
...
@@ -3,13 +3,15 @@ package chat.rocket.android.chatroom.adapter
import
android.text.method.LinkMovementMethod
import
android.view.View
import
chat.rocket.android.chatroom.viewmodel.MessageViewModel
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.avatar.view.*
import
kotlinx.android.synthetic.main.item_message.view.*
class
MessageViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
:
BaseViewHolder
<
MessageViewModel
>(
itemView
,
listener
)
{
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
MessageViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
View file @
fb5b651d
...
...
@@ -6,10 +6,13 @@ import android.view.View
import
chat.rocket.android.chatroom.viewmodel.UrlPreviewViewModel
import
chat.rocket.android.util.extensions.content
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.message_url_preview.view.*
class
UrlPreviewViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
:
BaseViewHolder
<
UrlPreviewViewModel
>(
itemView
,
listener
)
{
class
UrlPreviewViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
UrlPreviewViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/VideoAttachmentViewHolder.kt
View file @
fb5b651d
...
...
@@ -4,10 +4,13 @@ import android.view.View
import
chat.rocket.android.chatroom.viewmodel.VideoAttachmentViewModel
import
chat.rocket.android.player.PlayerActivity
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.message_attachment.view.*
class
VideoAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
:
BaseViewHolder
<
VideoAttachmentViewModel
>(
itemView
,
listener
)
{
class
VideoAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
VideoAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
fb5b651d
...
...
@@ -60,7 +60,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
// TODO: For now we are marking the room as read if we can get the messages (I mean, no exception occurs)
// but should mark only when the user see the first unread message.
markRoomAsRead
(
chatRoomId
)
val
messagesViewModels
=
mapper
.
map
(
messages
)
view
.
showMessages
(
messagesViewModels
)
...
...
@@ -97,7 +97,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
view
.
showGenericErrorMessage
()
}
}
finally
{
view
.
enableSendMessageButton
()
...
...
@@ -353,6 +353,23 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
/**
* Send an emoji reaction to a message.
*/
fun
react
(
messageId
:
String
,
emoji
:
String
)
{
launchUI
(
strategy
)
{
try
{
client
.
toggleReaction
(
messageId
,
emoji
.
removeSurrounding
(
":"
))
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
e
(
ex
)
}
}
}
fun
showReactions
(
messageId
:
String
)
{
view
.
showReactionsPopup
(
messageId
)
}
private
fun
updateMessage
(
streamedMessage
:
Message
)
{
launchUI
(
strategy
)
{
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
)
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
fb5b651d
...
...
@@ -105,4 +105,5 @@ interface ChatRoomView : LoadingView, MessageView {
* This user has joined the chat callback.
*/
fun
onJoined
()
fun
showReactionsPopup
(
messageId
:
String
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
fb5b651d
...
...
@@ -24,10 +24,7 @@ import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.helper.KeyboardHelper
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.widget.emoji.ComposerEditText
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.android.widget.emoji.*
import
chat.rocket.core.internal.realtime.State
import
dagger.android.support.AndroidSupportInjection
import
io.reactivex.disposables.CompositeDisposable
...
...
@@ -64,7 +61,7 @@ private const val REQUEST_CODE_FOR_PERFORM_SAF = 42
private
const
val
BUNDLE_CHAT_ROOM_LAST_SEEN
=
"chat_room_last_seen"
private
const
val
BUNDLE_CHAT_ROOM_IS_SUBSCRIBED
=
"chat_room_is_subscribed"
class
ChatRoomFragment
:
Fragment
(),
ChatRoomView
,
EmojiKeyboard
Popup
.
Listener
{
class
ChatRoomFragment
:
Fragment
(),
ChatRoomView
,
EmojiKeyboard
Listener
,
EmojiReaction
Listener
{
@Inject
lateinit
var
presenter
:
ChatRoomPresenter
@Inject
lateinit
var
parser
:
MessageParser
private
lateinit
var
adapter
:
ChatRoomAdapter
...
...
@@ -187,7 +184,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
activity
?.
apply
{
if
(
recycler_view
.
adapter
==
null
)
{
adapter
=
ChatRoomAdapter
(
chatRoomType
,
chatRoomName
,
presenter
)
adapter
=
ChatRoomAdapter
(
chatRoomType
,
chatRoomName
,
presenter
,
reactionListener
=
this
@ChatRoomFragment
)
recycler_view
.
adapter
=
adapter
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
true
)
linearLayoutManager
.
stackFromEnd
=
true
...
...
@@ -204,6 +202,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
val
oldMessagesCount
=
adapter
.
itemCount
adapter
.
appendData
(
dataSet
)
recycler_view
.
scrollToPosition
(
92
)
if
(
oldMessagesCount
==
0
&&
dataSet
.
isNotEmpty
())
{
recycler_view
.
scrollToPosition
(
0
)
}
...
...
@@ -248,7 +247,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
override
fun
dispatchUpdateMessage
(
index
:
Int
,
message
:
List
<
BaseViewModel
<*
>>)
{
adapter
.
updateItem
(
message
.
last
())
if
(
message
.
size
>
1
)
{
adapter
.
updateItem
(
message
.
last
())
adapter
.
prependData
(
listOf
(
message
.
first
()))
}
}
...
...
@@ -317,6 +315,26 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
}
}
override
fun
onReactionTouched
(
messageId
:
String
,
emojiShortname
:
String
)
{
presenter
.
react
(
messageId
,
emojiShortname
)
}
override
fun
onReactionAdded
(
messageId
:
String
,
emoji
:
Emoji
)
{
presenter
.
react
(
messageId
,
emoji
.
shortname
)
}
override
fun
showReactionsPopup
(
messageId
:
String
)
{
context
?.
let
{
val
emojiPickerPopup
=
EmojiPickerPopup
(
it
)
emojiPickerPopup
.
listener
=
object
:
EmojiListenerAdapter
()
{
override
fun
onEmojiAdded
(
emoji
:
Emoji
)
{
onReactionAdded
(
messageId
,
emoji
)
}
}
emojiPickerPopup
.
show
()
}
}
private
fun
setReactionButtonIcon
(
@DrawableRes
drawableId
:
Int
)
{
button_add_reaction
.
setImageResource
(
drawableId
)
button_add_reaction
.
setTag
(
drawableId
)
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/AudioAttachmentViewModel.kt
View file @
fb5b651d
...
...
@@ -10,8 +10,10 @@ data class AudioAttachmentViewModel(
override
val
messageId
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentTitle
:
CharSequence
,
override
val
id
:
Long
)
:
BaseFileAttachmentViewModel
<
AudioAttachment
>
{
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseFileAttachmentViewModel
<
AudioAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
AUDIO_ATTACHMENT
.
viewType
override
val
layoutId
:
Int
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
View file @
fb5b651d
...
...
@@ -9,6 +9,8 @@ interface BaseViewModel<out T> {
val
messageId
:
String
val
viewType
:
Int
val
layoutId
:
Int
var
reactions
:
List
<
ReactionViewModel
>
var
nextDownStreamMessage
:
BaseViewModel
<*>?
enum
class
ViewType
(
val
viewType
:
Int
)
{
MESSAGE
(
0
),
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ImageAttachmentViewModel.kt
View file @
fb5b651d
...
...
@@ -10,7 +10,9 @@ data class ImageAttachmentViewModel(
override
val
messageId
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentTitle
:
CharSequence
,
override
val
id
:
Long
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseFileAttachmentViewModel
<
ImageAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
IMAGE_ATTACHMENT
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/MessageViewModel.kt
View file @
fb5b651d
...
...
@@ -12,6 +12,8 @@ data class MessageViewModel(
override
val
senderName
:
CharSequence
,
override
val
content
:
CharSequence
,
override
val
isPinned
:
Boolean
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
var
isFirstUnread
:
Boolean
)
:
BaseMessageViewModel
<
Message
>
{
override
val
viewType
:
Int
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ReactionViewModel.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.chatroom.viewmodel
data class
ReactionViewModel
(
val
messageId
:
String
,
val
shortname
:
String
,
val
unicode
:
CharSequence
,
val
count
:
Int
,
val
usernames
:
List
<
String
>
=
emptyList
()
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/viewmodel/UrlPreviewViewModel.kt
View file @
fb5b651d
...
...
@@ -5,13 +5,15 @@ import chat.rocket.core.model.Message
import
chat.rocket.core.model.url.Url
data class
UrlPreviewViewModel
(
override
val
message
:
Message
,
override
val
rawData
:
Url
,
override
val
messageId
:
String
,
val
title
:
CharSequence
?,
val
hostname
:
String
,
val
description
:
CharSequence
?,
val
thumbUrl
:
String
?
override
val
message
:
Message
,
override
val
rawData
:
Url
,
override
val
messageId
:
String
,
val
title
:
CharSequence
?,
val
hostname
:
String
,
val
description
:
CharSequence
?,
val
thumbUrl
:
String
?,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseViewModel
<
Url
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
URL_PREVIEW
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/VideoAttachmentViewModel.kt
View file @
fb5b651d
...
...
@@ -10,7 +10,9 @@ data class VideoAttachmentViewModel(
override
val
messageId
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentTitle
:
CharSequence
,
override
val
id
:
Long
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseFileAttachmentViewModel
<
VideoAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
VIDEO_ATTACHMENT
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
View file @
fb5b651d
...
...
@@ -14,6 +14,7 @@ import chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.TokenRepository
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.MessageType
...
...
@@ -83,7 +84,8 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
title
=
url
.
meta
?.
title
val
description
=
url
.
meta
?.
description
return
UrlPreviewViewModel
(
message
,
url
,
message
.
id
,
title
,
hostname
,
description
,
thumb
)
return
UrlPreviewViewModel
(
message
,
url
,
message
.
id
,
title
,
hostname
,
description
,
thumb
,
getReactions
(
message
))
}
private
fun
mapAttachment
(
message
:
Message
,
attachment
:
Attachment
):
BaseViewModel
<
*
>?
{
...
...
@@ -99,11 +101,11 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
id
=
"${message.id}_${attachment.titleLink}"
.
hashCode
().
toLong
()
return
when
(
attachment
)
{
is
ImageAttachment
->
ImageAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
attachmentUrl
,
attachmentTitle
?:
""
,
id
)
attachmentUrl
,
attachmentTitle
?:
""
,
id
,
getReactions
(
message
)
)
is
VideoAttachment
->
VideoAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
attachmentUrl
,
attachmentTitle
?:
""
,
id
)
attachmentUrl
,
attachmentTitle
?:
""
,
id
,
getReactions
(
message
)
)
is
AudioAttachment
->
AudioAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
attachmentUrl
,
attachmentTitle
?:
""
,
id
)
attachmentUrl
,
attachmentTitle
?:
""
,
id
,
getReactions
(
message
)
)
else
->
null
}
}
...
...
@@ -149,7 +151,27 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
content
=
getContent
(
context
,
getMessageWithoutQuoteMarkdown
(
message
),
quote
)
MessageViewModel
(
message
=
getMessageWithoutQuoteMarkdown
(
message
),
rawData
=
message
,
messageId
=
message
.
id
,
avatar
=
avatar
!!
,
time
=
time
,
senderName
=
sender
,
content
=
content
,
isPinned
=
message
.
pinned
,
isFirstUnread
=
false
)
content
=
content
,
isPinned
=
message
.
pinned
,
reactions
=
getReactions
(
message
),
isFirstUnread
=
false
)
}
private
fun
getReactions
(
message
:
Message
):
List
<
ReactionViewModel
>
{
val
reactions
=
message
.
reactions
?.
let
{
val
list
=
mutableListOf
<
ReactionViewModel
>()
it
.
getShortNames
().
forEach
{
shortname
->
val
usernames
=
it
.
getUsernames
(
shortname
)
?:
emptyList
()
val
count
=
usernames
.
size
list
.
add
(
ReactionViewModel
(
messageId
=
message
.
id
,
shortname
=
shortname
,
unicode
=
EmojiParser
.
parse
(
shortname
),
count
=
count
,
usernames
=
usernames
)
)
}
list
}
return
reactions
?:
emptyList
()
}
private
fun
getMessageWithoutQuoteMarkdown
(
message
:
Message
):
Message
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/di/ChatRoomsFragmentModule.kt
View file @
fb5b651d
...
...
@@ -3,11 +3,9 @@ package chat.rocket.android.chatrooms.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@PerFragment
...
...
@@ -22,9 +20,4 @@ class ChatRoomsFragmentModule {
fun
provideLifecycleOwner
(
frag
:
ChatRoomsFragment
):
LifecycleOwner
{
return
frag
}
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
{
return
CancelStrategy
(
owner
,
jobs
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/di/ChatRoomsModule.kt
deleted
100644 → 0
View file @
31ff5935
package
chat.rocket.android.chatrooms.di
import
android.content.Context
import
chat.rocket.android.chatrooms.presentation.ChatRoomsNavigator
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.dagger.scope.PerActivity
import
dagger.Module
import
dagger.Provides
@Module
class
ChatRoomsModule
{
@Provides
@PerActivity
fun
provideChatRoomsNavigator
(
activity
:
MainActivity
,
context
:
Context
)
=
ChatRoomsNavigator
(
activity
,
context
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsNavigator.kt
deleted
100644 → 0
View file @
31ff5935
package
chat.rocket.android.chatrooms.presentation
import
android.content.Context
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.main.ui.MainActivity
class
ChatRoomsNavigator
(
private
val
activity
:
MainActivity
,
private
val
context
:
Context
)
{
fun
toChatRoom
(
chatRoomId
:
String
,
chatRoomName
:
String
,
chatRoomType
:
String
,
isChatRoomReadOnly
:
Boolean
,
chatRoomLastSeen
:
Long
,
isChatRoomSubscribed
:
Boolean
)
{
activity
.
startActivity
(
context
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
))
activity
.
overridePendingTransition
(
R
.
anim
.
open_enter
,
R
.
anim
.
open_exit
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
fb5b651d
package
chat.rocket.android.chatrooms.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.main.presentation.MainNavigator
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
...
...
@@ -24,7 +25,7 @@ import javax.inject.Inject
class
ChatRoomsPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomsView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
ChatRooms
Navigator
,
private
val
navigator
:
Main
Navigator
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
getChatRoomsInteractor
:
GetChatRoomsInteractor
,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
...
...
app/src/main/java/chat/rocket/android/dagger/LocalComponent.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.dagger
import
android.content.Context
import
chat.rocket.android.chatroom.adapter.MessageReactionsAdapter
import
chat.rocket.android.dagger.module.LocalModule
import
dagger.BindsInstance
import
dagger.Component
import
javax.inject.Singleton
@Singleton
@Component
(
modules
=
[
LocalModule
::
class
])
interface
LocalComponent
{
@Component
.
Builder
interface
Builder
{
@BindsInstance
fun
context
(
applicationContext
:
Context
):
Builder
fun
build
():
LocalComponent
}
fun
inject
(
adapter
:
MessageReactionsAdapter
.
SingleReactionViewHolder
)
fun
inject
(
adapter
:
MessageReactionsAdapter
.
AddReactionViewHolder
)
/*@Component.Builder
abstract class Builder : AndroidInjector.Builder<RocketChatApplication>()*/
}
app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
View file @
fb5b651d
...
...
@@ -11,9 +11,7 @@ import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatroom.ui.PinnedMessagesActivity
import
chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
import
chat.rocket.android.chatrooms.di.ChatRoomsModule
import
chat.rocket.android.dagger.scope.PerActivity
import
chat.rocket.android.main.di.MainActivityProvider
import
chat.rocket.android.main.di.MainModule
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.members.di.MembersFragmentProvider
...
...
@@ -37,8 +35,6 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
MainModule
::
class
,
MainActivityProvider
::
class
,
ChatRoomsModule
::
class
,
ChatRoomsFragmentProvider
::
class
,
ProfileFragmentProvider
::
class
])
...
...
app/src/main/java/chat/rocket/android/dagger/module/LocalModule.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.dagger.module
import
android.content.Context
import
android.content.SharedPreferences
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.SharedPrefsLocalRepository
import
dagger.Module
import
dagger.Provides
import
javax.inject.Singleton
@Module
class
LocalModule
{
@Provides
fun
provideSharedPreferences
(
context
:
Context
):
SharedPreferences
{
return
context
.
getSharedPreferences
(
"rocket.chat"
,
Context
.
MODE_PRIVATE
)
}
@Provides
@Singleton
fun
provideLocalRepository
(
prefs
:
SharedPreferences
):
LocalRepository
{
return
SharedPrefsLocalRepository
(
prefs
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/di/MainActivityModule.kt
deleted
100644 → 0
View file @
31ff5935
package
chat.rocket.android.main.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.main.ui.MainActivity
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
class
MainActivityModule
{
// @Provides
// fun provideMainView(activity: MainActivity): MainView = activity
@Provides
fun
provideLifecycleOwner
(
activity
:
MainActivity
):
LifecycleOwner
=
activity
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
=
CancelStrategy
(
owner
,
jobs
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/di/MainActivityProvider.kt
deleted
100644 → 0
View file @
31ff5935
package
chat.rocket.android.main.di
import
chat.rocket.android.main.ui.MainActivity
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
MainActivityProvider
{
@ContributesAndroidInjector
(
modules
=
[
MainActivityModule
::
class
])
abstract
fun
provideMainActivity
():
MainActivity
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/di/MainModule.kt
View file @
fb5b651d
package
chat.rocket.android.main.di
import
android.arch.lifecycle.LifecycleOwner
import
android.content.Context
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerActivity
import
chat.rocket.android.main.presentation.MainNavigator
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.main.ui.MainActivity
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
class
MainModule
{
...
...
@@ -13,4 +17,13 @@ class MainModule {
@Provides
@PerActivity
fun
provideMainNavigator
(
activity
:
MainActivity
,
context
:
Context
)
=
MainNavigator
(
activity
,
context
)
@Provides
fun
provideMainView
(
activity
:
MainActivity
):
MainView
=
activity
@Provides
fun
provideLifecycleOwner
(
activity
:
MainActivity
):
LifecycleOwner
=
activity
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
=
CancelStrategy
(
owner
,
jobs
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt
View file @
fb5b651d
...
...
@@ -2,6 +2,7 @@ package chat.rocket.android.main.presentation
import
android.content.Context
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.profile.ui.ProfileFragment
...
...
@@ -27,4 +28,15 @@ class MainNavigator(internal val activity: MainActivity, internal val context: C
SettingsFragment
.
newInstance
()
}
}
fun
toChatRoom
(
chatRoomId
:
String
,
chatRoomName
:
String
,
chatRoomType
:
String
,
isChatRoomReadOnly
:
Boolean
,
chatRoomLastSeen
:
Long
,
isChatRoomSubscribed
:
Boolean
)
{
activity
.
startActivity
(
context
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
))
activity
.
overridePendingTransition
(
R
.
anim
.
open_enter
,
R
.
anim
.
open_exit
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
fb5b651d
package
chat.rocket.android.main.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
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.RocketChatClient
import
chat.rocket.core.internal.realtime.disconnect
import
chat.rocket.core.internal.rest.logout
import
chat.rocket.core.internal.rest.unregisterPushToken
import
timber.log.Timber
import
javax.inject.Inject
class
MainPresenter
@Inject
constructor
(
private
val
navigator
:
MainNavigator
,
class
MainPresenter
@Inject
constructor
(
private
val
view
:
MainView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
MainNavigator
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
localRepository
:
LocalRepository
,
managerFactory
:
ConnectionManagerFactory
,
...
...
@@ -30,19 +35,21 @@ class MainPresenter @Inject constructor(private val navigator: MainNavigator,
* Logout from current server.
*/
fun
logout
()
{
// TODO: inject CancelStrategy, and MainView.
// launchUI(strategy) {
launchUI
(
strategy
)
{
try
{
//
clearTokens()
//
client.logout()
clearTokens
()
client
.
logout
()
//TODO: Add the code to unsubscribe to all subscriptions.
client
.
disconnect
()
// view.onLogout()
}
catch
(
e
:
RocketChatException
)
{
Timber
.
e
(
e
)
// view.showMessage(e.message!!)
view
.
onLogout
()
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
//
}
}
}
private
suspend
fun
clearTokens
()
{
...
...
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
fb5b651d
package
chat.rocket.android.main.ui
import
android.app.Activity
import
android.content.Intent
import
android.os.Bundle
import
android.support.v4.app.Fragment
...
...
@@ -7,25 +8,21 @@ import android.support.v7.app.AppCompatActivity
import
android.view.Gravity
import
android.view.MenuItem
import
chat.rocket.android.R
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.profile.ui.ProfileFragment
import
chat.rocket.android.settings.ui.SettingsFragment
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.main.presentation.MainPresenter
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.util.extensions.showToast
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
import
dagger.android.DispatchingAndroidInjector
import
dagger.android.HasActivityInjector
import
dagger.android.support.HasSupportFragmentInjector
import
kotlinx.android.synthetic.main.activity_main.*
import
kotlinx.android.synthetic.main.app_bar.*
import
javax.inject.Inject
class
MainActivity
:
AppCompatActivity
(),
MainView
,
HasSupportFragmentInjector
{
class
MainActivity
:
AppCompatActivity
(),
MainView
,
HasActivityInjector
,
HasSupportFragmentInjector
{
@Inject
lateinit
var
activityDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Activity
>
@Inject
lateinit
var
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
@Inject
lateinit
var
presenter
:
MainPresenter
private
var
isFragmentAdded
:
Boolean
=
false
...
...
@@ -68,6 +65,8 @@ class MainActivity : AppCompatActivity(), MainView, HasSupportFragmentInjector {
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
activityInjector
():
AndroidInjector
<
Activity
>
=
activityDispatchingAndroidInjector
override
fun
supportFragmentInjector
():
AndroidInjector
<
Fragment
>
=
fragmentDispatchingAndroidInjector
private
fun
setupToolbar
()
{
...
...
app/src/main/java/chat/rocket/android/profile/di/ProfileFragmentModule.kt
View file @
fb5b651d
package
chat.rocket.android.profile.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.profile.presentation.ProfileView
import
chat.rocket.android.profile.ui.ProfileFragment
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@PerFragment
...
...
@@ -22,9 +20,4 @@ class ProfileFragmentModule {
fun
provideLifecycleOwner
(
frag
:
ProfileFragment
):
LifecycleOwner
{
return
frag
}
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
{
return
CancelStrategy
(
owner
,
jobs
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/widget/emoji/CategoryPagerAdapter.kt
View file @
fb5b651d
...
...
@@ -9,10 +9,10 @@ import android.view.View
import
android.view.ViewGroup
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup.Listener
import
java.util.*
class
CategoryPagerAdapter
(
val
listener
:
Listener
)
:
PagerAdapter
()
{
class
CategoryPagerAdapter
(
val
listener
:
EmojiKeyboardListener
)
:
PagerAdapter
()
{
override
fun
isViewFromObject
(
view
:
View
,
obj
:
Any
):
Boolean
{
return
view
==
obj
}
...
...
@@ -46,7 +46,7 @@ class CategoryPagerAdapter(val listener: Listener) : PagerAdapter() {
override
fun
getPageTitle
(
position
:
Int
)
=
EmojiCategory
.
values
()[
position
].
textIcon
()
class
EmojiAdapter
(
val
spanCount
:
Int
,
val
listener
:
Listener
)
:
RecyclerView
.
Adapter
<
EmojiRowViewHolder
>()
{
class
EmojiAdapter
(
val
spanCount
:
Int
,
val
listener
:
EmojiKeyboard
Listener
)
:
RecyclerView
.
Adapter
<
EmojiRowViewHolder
>()
{
private
var
emojis
=
Collections
.
emptyList
<
Emoji
>()
fun
addEmojis
(
emojis
:
List
<
Emoji
>)
{
...
...
@@ -66,7 +66,7 @@ class CategoryPagerAdapter(val listener: Listener) : PagerAdapter() {
override
fun
getItemCount
():
Int
=
emojis
.
size
}
class
EmojiRowViewHolder
(
itemView
:
View
,
val
itemCount
:
Int
,
val
spanCount
:
Int
,
val
listener
:
Listener
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
class
EmojiRowViewHolder
(
itemView
:
View
,
val
itemCount
:
Int
,
val
spanCount
:
Int
,
val
listener
:
EmojiKeyboard
Listener
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
private
val
emojiView
:
TextView
=
itemView
.
findViewById
(
R
.
id
.
emoji
)
fun
bind
(
emoji
:
Emoji
)
{
...
...
app/src/main/java/chat/rocket/android/widget/emoji/EmojiKeyboardListener.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.widget.emoji
interface
EmojiKeyboardListener
{
/**
* When an emoji is selected on the picker.
*
* @param emoji The selected emoji
*/
fun
onEmojiAdded
(
emoji
:
Emoji
)
/**
* When backspace key is clicked.
*
* @param keyCode The key code pressed as defined
*
* @see android.view.KeyEvent
*/
fun
onNonEmojiKeyPressed
(
keyCode
:
Int
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/widget/emoji/EmojiKeyboardPopup.kt
View file @
fb5b651d
...
...
@@ -21,14 +21,14 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
private
lateinit
var
searchView
:
View
private
lateinit
var
backspaceView
:
View
private
lateinit
var
parentContainer
:
ViewGroup
var
listener
:
Listener
?
=
null
var
listener
:
EmojiKeyboard
Listener
?
=
null
companion
object
{
const
val
PREF_EMOJI_RECENTS
=
"PREF_EMOJI_RECENTS"
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
):
View
{
val
view
=
inflater
.
inflate
(
R
.
layout
.
emoji_
popup_layout
,
null
,
false
)
val
view
=
inflater
.
inflate
(
R
.
layout
.
emoji_
keyboard
,
null
)
parentContainer
=
view
.
findViewById
(
R
.
id
.
emoji_keyboard_container
)
viewPager
=
view
.
findViewById
(
R
.
id
.
pager_categories
)
searchView
=
view
.
findViewById
(
R
.
id
.
emoji_search
)
...
...
@@ -55,20 +55,17 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
private
fun
setupViewPager
()
{
context
.
let
{
val
callback
=
when
(
it
)
{
is
Listener
->
it
is
EmojiKeyboard
Listener
->
it
else
->
{
val
fragments
=
(
it
as
AppCompatActivity
).
supportFragmentManager
.
fragments
if
(
fragments
==
null
||
fragments
.
size
==
0
||
!(
fragments
[
0
]
is
Listener
))
{
if
(
fragments
==
null
||
fragments
.
size
==
0
||
!(
fragments
[
0
]
is
EmojiKeyboard
Listener
))
{
throw
IllegalStateException
(
"activity/fragment should implement Listener interface"
)
}
fragments
[
0
]
as
Listener
fragments
[
0
]
as
EmojiKeyboard
Listener
}
}
viewPager
.
adapter
=
CategoryPagerAdapter
(
object
:
Listener
{
override
fun
onNonEmojiKeyPressed
(
keyCode
:
Int
)
{
// do nothing
}
viewPager
.
adapter
=
CategoryPagerAdapter
(
object
:
EmojiListenerAdapter
()
{
override
fun
onEmojiAdded
(
emoji
:
Emoji
)
{
EmojiRepository
.
addToRecents
(
emoji
)
callback
.
onEmojiAdded
(
emoji
)
...
...
@@ -78,14 +75,14 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
for
(
category
in
EmojiCategory
.
values
())
{
val
tab
=
tabLayout
.
getTabAt
(
category
.
ordinal
)
val
tabView
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
emoji_picker_tab
,
null
)
tab
?.
setCustomView
(
tabView
)
tab
?.
customView
=
tabView
val
textView
=
tabView
.
findViewById
(
R
.
id
.
image_category
)
as
ImageView
textView
.
setImageResource
(
category
.
resourceIcon
())
}
val
currentTab
=
if
(
EmojiRepository
.
getRecents
().
isEmpty
())
EmojiCategory
.
PEOPLE
.
ordinal
else
EmojiCategory
.
RECENTS
.
ordinal
viewPager
.
setCurrentItem
(
currentTab
)
viewPager
.
currentItem
=
currentTab
}
}
...
...
@@ -132,22 +129,4 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
override
fun
onTextChanged
(
s
:
CharSequence
,
start
:
Int
,
before
:
Int
,
count
:
Int
)
{
}
}
interface
Listener
{
/**
* When an emoji is selected on the picker.
*
* @param emoji The selected emoji
*/
fun
onEmojiAdded
(
emoji
:
Emoji
)
/**
* When backspace key is clicked.
*
* @param keyCode The key code pressed as defined
*
* @see android.view.KeyEvent
*/
fun
onNonEmojiKeyPressed
(
keyCode
:
Int
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/widget/emoji/EmojiListenerAdapter.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.widget.emoji
abstract
class
EmojiListenerAdapter
:
EmojiKeyboardListener
{
override
fun
onEmojiAdded
(
emoji
:
Emoji
)
{
// this space is for rent
}
override
fun
onNonEmojiKeyPressed
(
keyCode
:
Int
)
{
// this space is for rent
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/widget/emoji/EmojiPickerPopup.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.widget.emoji
import
android.app.Dialog
import
android.content.Context
import
android.os.Bundle
import
android.support.design.widget.TabLayout
import
android.support.v4.view.ViewPager
import
android.view.LayoutInflater
import
android.view.Window
import
android.view.WindowManager
import
android.widget.ImageView
import
chat.rocket.android.R
class
EmojiPickerPopup
(
context
:
Context
)
:
Dialog
(
context
)
{
private
lateinit
var
viewPager
:
ViewPager
private
lateinit
var
tabLayout
:
TabLayout
var
listener
:
EmojiKeyboardListener
?
=
null
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
requestWindowFeature
(
Window
.
FEATURE_NO_TITLE
)
setContentView
(
R
.
layout
.
emoji_picker
)
viewPager
=
findViewById
(
R
.
id
.
pager_categories
)
tabLayout
=
findViewById
(
R
.
id
.
tabs
)
tabLayout
.
setupWithViewPager
(
viewPager
)
setupViewPager
()
setSize
()
}
private
fun
setSize
()
{
val
lp
=
WindowManager
.
LayoutParams
()
lp
.
copyFrom
(
window
.
attributes
)
val
dialogWidth
=
lp
.
width
val
dialogHeight
=
context
.
resources
.
getDimensionPixelSize
(
R
.
dimen
.
picker_popup_height
)
window
.
setLayout
(
dialogWidth
,
dialogHeight
)
}
private
fun
setupViewPager
()
{
viewPager
.
adapter
=
CategoryPagerAdapter
(
object
:
EmojiListenerAdapter
()
{
override
fun
onEmojiAdded
(
emoji
:
Emoji
)
{
EmojiRepository
.
addToRecents
(
emoji
)
dismiss
()
listener
?.
onEmojiAdded
(
emoji
)
}
})
for
(
category
in
EmojiCategory
.
values
())
{
val
tab
=
tabLayout
.
getTabAt
(
category
.
ordinal
)
val
tabView
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
emoji_picker_tab
,
null
)
tab
?.
customView
=
tabView
val
textView
=
tabView
.
findViewById
(
R
.
id
.
image_category
)
as
ImageView
textView
.
setImageResource
(
category
.
resourceIcon
())
}
val
currentTab
=
if
(
EmojiRepository
.
getRecents
().
isEmpty
())
EmojiCategory
.
PEOPLE
.
ordinal
else
EmojiCategory
.
RECENTS
.
ordinal
viewPager
.
currentItem
=
currentTab
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/widget/emoji/EmojiReactionListener.kt
0 → 100644
View file @
fb5b651d
package
chat.rocket.android.widget.emoji
interface
EmojiReactionListener
{
/**
* Callback when an emoji is picked in respect to message by the given id.
*
* @param messageId The id of the message being reacted.
* @param emoji The emoji used to react.
*/
fun
onReactionAdded
(
messageId
:
String
,
emoji
:
Emoji
)
/**
* Callback when an added reaction is touched.
*
* @param messageId The id of the message with the reaction.
* @param emojiShortname The shortname of the emoji (:grin:, :smiley:, etc).
*/
fun
onReactionTouched
(
messageId
:
String
,
emojiShortname
:
String
)
}
\ No newline at end of file
app/src/main/res/drawable/ic_add_reaction.xml
0 → 100644
View file @
fb5b651d
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportHeight=
"20.0"
android:viewportWidth=
"20.0"
>
<path
android:fillColor=
"#868585"
android:fillType=
"evenOdd"
android:pathData=
"M12,8m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
/>
<path
android:fillColor=
"#868585"
android:fillType=
"evenOdd"
android:pathData=
"M8,8m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
/>
<path
android:fillType=
"evenOdd"
android:pathData=
"M10,3a7,7 0,1 0,0 14,7 7,0 0,0 7,-7M7.172,12.328a4,4 0,0 0,5.656 0"
android:strokeColor=
"#868585"
android:strokeWidth=
"1.5"
/>
<path
android:fillType=
"evenOdd"
android:pathData=
"M16.2,1.2v5.2m-2.6,-2.6h5.2"
android:strokeColor=
"#868585"
android:strokeLineCap=
"square"
android:strokeWidth=
"1.5"
/>
</vector>
app/src/main/res/drawable/rounded_background.xml
0 → 100644
View file @
fb5b651d
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"rectangle"
>
<size
android:width=
"24dp"
android:height=
"24dp"
/>
<solid
android:color=
"#efeeee"
/>
<corners
android:radius=
"4dp"
/>
</shape>
\ No newline at end of file
app/src/main/res/layout/emoji_
popup_layout
.xml
→
app/src/main/res/layout/emoji_
keyboard
.xml
View file @
fb5b651d
...
...
@@ -11,35 +11,18 @@
android:layout_width=
"match_parent"
android:layout_height=
"1dp"
android:background=
"@color/colorDividerMessageComposer"
app:layout_constraintBottom_toTopOf=
"@+id/
tabs
"
app:layout_constraintBottom_toTopOf=
"@+id/
picker_container
"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
<android.support.design.widget.TabLayout
android:id=
"@+id/tabs"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
app:layout_constraintBottom_toTopOf=
"@+id/pager_categories"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:tabBackground=
"@color/whitesmoke"
app:tabGravity=
"fill"
app:tabMaxWidth=
"48dp"
app:tabMode=
"scrollable"
/>
<android.support.v4.view.ViewPager
android:id=
"@+id/pager_categories"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:layout_marginEnd=
"8dp"
android:layout_marginStart=
"8dp"
android:background=
"@color/white"
<include
android:id=
"@+id/picker_container"
layout=
"@layout/emoji_picker"
app:layout_constraintBottom_toTopOf=
"@+id/emoji_actions_container"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_to
BottomOf=
"@+id/tabs
"
/>
app:layout_constraintTop_to
TopOf=
"parent
"
/>
<RelativeLayout
android:id=
"@+id/emoji_actions_container"
...
...
@@ -60,8 +43,8 @@
android:clickable=
"true"
android:focusable=
"true"
android:padding=
"8dp"
android:
visibility=
"invisible
"
android:
src=
"@drawable/ic_search_gray_24px
"
/>
android:
src=
"@drawable/ic_search_gray_24px
"
android:
visibility=
"invisible
"
/>
<ImageView
android:id=
"@+id/emoji_backspace"
...
...
app/src/main/res/layout/emoji_picker.xml
0 → 100644
View file @
fb5b651d
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:id=
"@+id/picker_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/white"
android:orientation=
"vertical"
>
<android.support.design.widget.TabLayout
android:id=
"@+id/tabs"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
app:tabBackground=
"@color/whitesmoke"
app:tabGravity=
"fill"
app:tabMaxWidth=
"48dp"
app:tabMode=
"scrollable"
/>
<android.support.v4.view.ViewPager
android:id=
"@+id/pager_categories"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_marginEnd=
"8dp"
android:layout_marginStart=
"8dp"
android:background=
"@color/white"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/item_add_reaction.xml
0 → 100644
View file @
fb5b651d
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"32dp"
android:layout_height=
"32dp"
android:paddingBottom=
"2dp"
android:paddingEnd=
"4dp"
android:paddingLeft=
"4dp"
android:paddingRight=
"4dp"
android:paddingStart=
"4dp"
android:paddingTop=
"2dp"
android:src=
"@drawable/ic_add_reaction"
/>
\ No newline at end of file
app/src/main/res/layout/item_message.xml
View file @
fb5b651d
...
...
@@ -74,11 +74,18 @@
style=
"@style/Message.TextView"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"5dp"
android:layout_marginBottom=
"2dp"
android:layout_marginTop=
"5dp"
app:layout_constraintLeft_toLeftOf=
"@id/top_container"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/top_container"
tools:text=
"This is a multiline chat message from Bertie that will take more than just one line of text. I have sure that everything is amazing!"
/>
<include
layout=
"@layout/layout_reactions"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
app:layout_constraintEnd_toEndOf=
"@+id/text_content"
app:layout_constraintStart_toStartOf=
"@+id/text_content"
app:layout_constraintTop_toBottomOf=
"@+id/text_content"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/item_reaction.xml
0 → 100644
View file @
fb5b651d
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"2dp"
android:layout_marginRight=
"2dp"
android:layout_marginTop=
"2dp"
android:layout_marginBottom=
"2dp"
android:descendantFocusability=
"beforeDescendants"
android:background=
"@drawable/rounded_background"
android:orientation=
"horizontal"
>
<TextView
android:id=
"@+id/text_emoji"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:ellipsize=
"end"
android:maxLines=
"1"
android:paddingLeft=
"4dp"
android:paddingStart=
"4dp"
android:textColor=
"#868585"
android:textSize=
"16sp"
tools:text=
":)"
/>
<TextView
android:id=
"@+id/text_count"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:gravity=
"center"
android:paddingBottom=
"4dp"
android:paddingEnd=
"4dp"
android:paddingLeft=
"4dp"
android:paddingRight=
"4dp"
android:paddingStart=
"4dp"
android:paddingTop=
"4dp"
android:textColor=
"#868585"
android:textSize=
"16sp"
android:textStyle=
"bold"
tools:text=
"12"
/>
</LinearLayout>
app/src/main/res/layout/layout_reactions.xml
0 → 100644
View file @
fb5b651d
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/recycler_view_reactions"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
\ No newline at end of file
app/src/main/res/layout/message_attachment.xml
View file @
fb5b651d
...
...
@@ -6,9 +6,9 @@
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?android:attr/selectableItemBackground"
android:
paddingStart=
"72dp
"
android:
orientation=
"vertical
"
android:paddingEnd=
"@dimen/screen_edge_left_and_right_margins"
android:
orientation=
"vertical
"
>
android:
paddingStart=
"72dp
"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_attachment"
...
...
@@ -39,4 +39,9 @@
android:layout_height=
"wrap_content"
tools:text=
"Filename.png"
/>
<include
layout=
"@layout/layout_reactions"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/message_url_preview.xml
View file @
fb5b651d
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/url_preview_layout"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?android:attr/selectableItemBackground"
android:padding
Start=
"72
dp"
android:padding
End=
"24
dp"
>
android:padding
End=
"24
dp"
android:padding
Start=
"72
dp"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_preview"
android:layout_width=
"70dp"
android:layout_height=
"50dp"
app:actualImageScaleType=
"centerCrop"
/>
app:actualImageScaleType=
"centerCrop"
/>
<TextView
android:id=
"@+id/text_host"
...
...
@@ -22,26 +21,33 @@
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:textColor=
"@color/colorSecondaryText"
tools:text=
"www.uol.com.br"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toEndOf=
"@+id/image_preview"
/>
app:layout_constraintStart_toEndOf=
"@+id/image_preview"
tools:text=
"www.uol.com.br"
/>
<TextView
android:id=
"@+id/text_title"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:textColor=
"@color/colorAccent"
tools:text=
"Web page title"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"@+id/text_host"
app:layout_constraintTop_toBottomOf=
"@id/text_host"
/>
app:layout_constraintTop_toBottomOf=
"@id/text_host"
tools:text=
"Web page title"
/>
<TextView
android:id=
"@+id/text_description"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
tools:text=
"description"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"@+id/text_host"
app:layout_constraintTop_toBottomOf=
"@id/text_title"
/>
app:layout_constraintTop_toBottomOf=
"@id/text_title"
tools:text=
"description"
/>
<include
layout=
"@layout/layout_reactions"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
app:layout_constraintStart_toStartOf=
"@+id/image_preview"
app:layout_constraintTop_toBottomOf=
"@+id/text_description"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/menu/message_actions.xml
View file @
fb5b651d
...
...
@@ -22,6 +22,11 @@
android:icon=
"@drawable/ic_content_copy_black_24px"
android:title=
"@string/action_msg_copy"
/>
<item
android:id=
"@+id/action_menu_msg_react"
android:icon=
"@drawable/ic_add_reaction"
android:title=
"@string/action_msg_add_reaction"
/>
<!--<item-->
<!--android:id="@+id/action_menu_msg_share"-->
<!--andrtextIconicon="@drawable/ic_share_black_24px"-->
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
fb5b651d
...
...
@@ -87,10 +87,11 @@
<string
name=
"action_msg_quote"
>
Citar
</string>
<string
name=
"action_msg_delete"
>
Remover
</string>
<string
name=
"action_msg_pin"
>
Fixar Mensagem
</string>
<string
name=
"action_msg_unpin"
>
Desafixar Me
s
sagem
</string>
<string
name=
"action_msg_unpin"
>
Desafixar Me
n
sagem
</string>
<string
name=
"action_msg_star"
>
Favoritar Mensagem
</string>
<string
name=
"action_msg_share"
>
Compartilhar
</string>
<string
name=
"action_title_editing"
>
Editando Mensagem
</string>
<string
name=
"action_msg_add_reaction"
>
Adicionar reação
</string>
<!-- Permission messages -->
<string
name=
"permission_editing_not_allowed"
>
Edição não permitida
</string>
...
...
app/src/main/res/values/dimens.xml
View file @
fb5b651d
...
...
@@ -24,6 +24,8 @@
<!-- Emoji -->
<dimen
name=
"picker_padding_bottom"
>
16dp
</dimen>
<dimen
name=
"supposed_keyboard_height"
>
252dp
</dimen>
<dimen
name=
"picker_popup_height"
>
250dp
</dimen>
<dimen
name=
"picker_popup_width"
>
300dp
</dimen>
<!-- Message -->
<dimen
name=
"padding_quote"
>
8dp
</dimen>
...
...
app/src/main/res/values/strings.xml
View file @
fb5b651d
...
...
@@ -92,6 +92,7 @@
<string
name=
"action_msg_star"
>
Star Message
</string>
<string
name=
"action_msg_share"
>
Share
</string>
<string
name=
"action_title_editing"
>
Editing Message
</string>
<string
name=
"action_msg_add_reaction"
>
Add reaction
</string>
<!-- Permission messages -->
<string
name=
"permission_editing_not_allowed"
>
Editing is not allowed
</string>
...
...
dependencies.gradle
View file @
fb5b651d
...
...
@@ -30,6 +30,7 @@ ext {
markwon
:
'1.0.3'
,
sheetMenu
:
'1.3.3'
,
aVLoadingIndicatorView
:
'2.1.3'
,
flexbox
:
'0.3.2'
,
// For testing
junit
:
'4.12'
,
...
...
@@ -49,6 +50,7 @@ ext {
design
:
"com.android.support:design:${versions.support}"
,
constraintLayout
:
"com.android.support.constraint:constraint-layout:${versions.constraintLayout}"
,
cardView
:
"com.android.support:cardview-v7:${versions.support}"
,
flexbox
:
"com.google.android:flexbox:${versions.flexbox}"
,
androidKtx
:
"androidx.core:core-ktx:${versions.androidKtx}"
,
...
...
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