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 {
...
@@ -59,6 +59,7 @@ dependencies {
implementation
libraries
.
design
implementation
libraries
.
design
implementation
libraries
.
constraintLayout
implementation
libraries
.
constraintLayout
implementation
libraries
.
cardView
implementation
libraries
.
cardView
implementation
libraries
.
flexbox
implementation
libraries
.
androidKtx
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
...
@@ -4,10 +4,13 @@ import android.view.View
import
chat.rocket.android.chatroom.viewmodel.AudioAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.AudioAttachmentViewModel
import
chat.rocket.android.player.PlayerActivity
import
chat.rocket.android.player.PlayerActivity
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.message_attachment.view.*
import
kotlinx.android.synthetic.main.message_attachment.view.*
class
AudioAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
class
AudioAttachmentViewHolder
(
itemView
:
View
,
:
BaseViewHolder
<
AudioAttachmentViewModel
>(
itemView
,
listener
)
{
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
AudioAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
init
{
with
(
itemView
)
{
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
...
@@ -7,16 +7,22 @@ import chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.bottomsheet.BottomSheetMenu
import
chat.rocket.android.chatroom.ui.bottomsheet.BottomSheetMenu
import
chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter
import
chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
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.Message
import
chat.rocket.core.model.isSystemMessage
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.inflate
import
ru.whalemare.sheetmenu.extension.toList
import
ru.whalemare.sheetmenu.extension.toList
abstract
class
BaseViewHolder
<
T
:
BaseViewModel
<*>>(
abstract
class
BaseViewHolder
<
T
:
BaseViewModel
<*>>(
itemView
:
View
,
itemView
:
View
,
private
val
listener
:
ActionsListener
private
val
listener
:
ActionsListener
,
var
reactionListener
:
EmojiReactionListener
?
=
null
)
:
RecyclerView
.
ViewHolder
(
itemView
),
)
:
RecyclerView
.
ViewHolder
(
itemView
),
MenuItem
.
OnMenuItemClickListener
{
MenuItem
.
OnMenuItemClickListener
{
var
data
:
T
?
=
null
var
data
:
T
?
=
null
init
{
init
{
...
@@ -26,6 +32,39 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
...
@@ -26,6 +32,39 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
fun
bind
(
data
:
T
)
{
fun
bind
(
data
:
T
)
{
this
.
data
=
data
this
.
data
=
data
bindViews
(
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
)
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
...
@@ -7,6 +7,7 @@ import chat.rocket.android.R
import
chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import
chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import
chat.rocket.android.chatroom.viewmodel.*
import
chat.rocket.android.chatroom.viewmodel.*
import
chat.rocket.android.util.extensions.inflate
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.Message
import
chat.rocket.core.model.isSystemMessage
import
chat.rocket.core.model.isSystemMessage
import
timber.log.Timber
import
timber.log.Timber
...
@@ -16,7 +17,8 @@ class ChatRoomAdapter(
...
@@ -16,7 +17,8 @@ class ChatRoomAdapter(
private
val
roomType
:
String
,
private
val
roomType
:
String
,
private
val
roomName
:
String
,
private
val
roomName
:
String
,
private
val
presenter
:
ChatRoomPresenter
?,
private
val
presenter
:
ChatRoomPresenter
?,
private
val
enableActions
:
Boolean
=
true
private
val
enableActions
:
Boolean
=
true
,
private
val
reactionListener
:
EmojiReactionListener
?
=
null
)
:
RecyclerView
.
Adapter
<
BaseViewHolder
<*>>()
{
)
:
RecyclerView
.
Adapter
<
BaseViewHolder
<*>>()
{
private
val
dataSet
=
ArrayList
<
BaseViewModel
<*>>()
private
val
dataSet
=
ArrayList
<
BaseViewModel
<*>>()
...
@@ -29,23 +31,23 @@ class ChatRoomAdapter(
...
@@ -29,23 +31,23 @@ class ChatRoomAdapter(
return
when
(
viewType
.
toViewType
())
{
return
when
(
viewType
.
toViewType
())
{
BaseViewModel
.
ViewType
.
MESSAGE
->
{
BaseViewModel
.
ViewType
.
MESSAGE
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
item_message
)
val
view
=
parent
.
inflate
(
R
.
layout
.
item_message
)
MessageViewHolder
(
view
,
actionsListener
)
MessageViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
}
BaseViewModel
.
ViewType
.
IMAGE_ATTACHMENT
->
{
BaseViewModel
.
ViewType
.
IMAGE_ATTACHMENT
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
ImageAttachmentViewHolder
(
view
,
actionsListener
)
ImageAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
}
BaseViewModel
.
ViewType
.
AUDIO_ATTACHMENT
->
{
BaseViewModel
.
ViewType
.
AUDIO_ATTACHMENT
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
AudioAttachmentViewHolder
(
view
,
actionsListener
)
AudioAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
}
BaseViewModel
.
ViewType
.
VIDEO_ATTACHMENT
->
{
BaseViewModel
.
ViewType
.
VIDEO_ATTACHMENT
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
val
view
=
parent
.
inflate
(
R
.
layout
.
message_attachment
)
VideoAttachmentViewHolder
(
view
,
actionsListener
)
VideoAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
}
BaseViewModel
.
ViewType
.
URL_PREVIEW
->
{
BaseViewModel
.
ViewType
.
URL_PREVIEW
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
message_url_preview
)
val
view
=
parent
.
inflate
(
R
.
layout
.
message_url_preview
)
UrlPreviewViewHolder
(
view
,
actionsListener
)
UrlPreviewViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
}
else
->
{
else
->
{
throw
InvalidParameterException
(
"TODO - implement for ${viewType.toViewType()}"
)
throw
InvalidParameterException
(
"TODO - implement for ${viewType.toViewType()}"
)
...
@@ -62,6 +64,23 @@ class ChatRoomAdapter(
...
@@ -62,6 +64,23 @@ class ChatRoomAdapter(
}
}
override
fun
onBindViewHolder
(
holder
:
BaseViewHolder
<
*
>,
position
:
Int
)
{
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
)
{
when
(
holder
)
{
is
MessageViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageViewModel
)
is
MessageViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageViewModel
)
is
ImageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ImageAttachmentViewModel
)
is
ImageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ImageAttachmentViewModel
)
...
@@ -97,12 +116,17 @@ class ChatRoomAdapter(
...
@@ -97,12 +116,17 @@ class ChatRoomAdapter(
}
}
fun
updateItem
(
message
:
BaseViewModel
<
*
>)
{
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
}
val
indexOfFirst
=
dataSet
.
indexOfFirst
{
it
.
messageId
==
message
.
messageId
}
Timber
.
d
(
"index: $index"
)
Timber
.
d
(
"index: $index"
)
if
(
index
>
-
1
)
{
if
(
index
>
-
1
)
{
message
.
nextDownStreamMessage
=
dataSet
[
index
].
nextDownStreamMessage
dataSet
[
index
]
=
message
dataSet
[
index
]
=
message
notifyItemChanged
(
index
)
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
// Delete message only if current is a system message update, i.e.: Message Removed
if
(
message
.
message
.
isSystemMessage
()
&&
indexOfFirst
>
-
1
&&
indexOfFirst
!=
index
)
{
if
(
message
.
message
.
isSystemMessage
()
&&
indexOfFirst
>
-
1
&&
indexOfFirst
!=
index
)
{
dataSet
.
removeAt
(
indexOfFirst
)
dataSet
.
removeAt
(
indexOfFirst
)
...
@@ -143,6 +167,7 @@ class ChatRoomAdapter(
...
@@ -143,6 +167,7 @@ class ChatRoomAdapter(
}
}
}
}
}
}
R
.
id
.
action_menu_msg_react
->
presenter
?.
showReactions
(
id
)
else
->
TODO
(
"Not implemented"
)
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
...
@@ -2,11 +2,14 @@ package chat.rocket.android.chatroom.adapter
import
android.view.View
import
android.view.View
import
chat.rocket.android.chatroom.viewmodel.ImageAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.ImageAttachmentViewModel
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
com.stfalcon.frescoimageviewer.ImageViewer
import
com.stfalcon.frescoimageviewer.ImageViewer
import
kotlinx.android.synthetic.main.message_attachment.view.*
import
kotlinx.android.synthetic.main.message_attachment.view.*
class
ImageAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
class
ImageAttachmentViewHolder
(
itemView
:
View
,
:
BaseViewHolder
<
ImageAttachmentViewModel
>(
itemView
,
listener
)
{
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
ImageAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
init
{
with
(
itemView
)
{
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
...
@@ -3,13 +3,15 @@ package chat.rocket.android.chatroom.adapter
import
android.text.method.LinkMovementMethod
import
android.text.method.LinkMovementMethod
import
android.view.View
import
android.view.View
import
chat.rocket.android.chatroom.viewmodel.MessageViewModel
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.avatar.view.*
import
kotlinx.android.synthetic.main.item_message.view.*
import
kotlinx.android.synthetic.main.item_message.view.*
class
MessageViewHolder
(
class
MessageViewHolder
(
itemView
:
View
,
itemView
:
View
,
listener
:
ActionsListener
listener
:
ActionsListener
,
)
:
BaseViewHolder
<
MessageViewModel
>(
itemView
,
listener
)
{
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
MessageViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
init
{
with
(
itemView
)
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
View file @
fb5b651d
...
@@ -6,10 +6,13 @@ import android.view.View
...
@@ -6,10 +6,13 @@ import android.view.View
import
chat.rocket.android.chatroom.viewmodel.UrlPreviewViewModel
import
chat.rocket.android.chatroom.viewmodel.UrlPreviewViewModel
import
chat.rocket.android.util.extensions.content
import
chat.rocket.android.util.extensions.content
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.message_url_preview.view.*
import
kotlinx.android.synthetic.main.message_url_preview.view.*
class
UrlPreviewViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
class
UrlPreviewViewHolder
(
itemView
:
View
,
:
BaseViewHolder
<
UrlPreviewViewModel
>(
itemView
,
listener
)
{
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
UrlPreviewViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
init
{
with
(
itemView
)
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/VideoAttachmentViewHolder.kt
View file @
fb5b651d
...
@@ -4,10 +4,13 @@ import android.view.View
...
@@ -4,10 +4,13 @@ import android.view.View
import
chat.rocket.android.chatroom.viewmodel.VideoAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.VideoAttachmentViewModel
import
chat.rocket.android.player.PlayerActivity
import
chat.rocket.android.player.PlayerActivity
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.message_attachment.view.*
import
kotlinx.android.synthetic.main.message_attachment.view.*
class
VideoAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
)
class
VideoAttachmentViewHolder
(
itemView
:
View
,
:
BaseViewHolder
<
VideoAttachmentViewModel
>(
itemView
,
listener
)
{
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
VideoAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
init
{
with
(
itemView
)
{
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,
...
@@ -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)
// 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.
// but should mark only when the user see the first unread message.
markRoomAsRead
(
chatRoomId
)
markRoomAsRead
(
chatRoomId
)
val
messagesViewModels
=
mapper
.
map
(
messages
)
val
messagesViewModels
=
mapper
.
map
(
messages
)
view
.
showMessages
(
messagesViewModels
)
view
.
showMessages
(
messagesViewModels
)
...
@@ -97,7 +97,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -97,7 +97,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
ex
.
message
?.
let
{
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
view
.
showMessage
(
it
)
}.
ifNull
{
}.
ifNull
{
view
.
showGenericErrorMessage
()
view
.
showGenericErrorMessage
()
}
}
}
finally
{
}
finally
{
view
.
enableSendMessageButton
()
view
.
enableSendMessageButton
()
...
@@ -353,6 +353,23 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -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
)
{
private
fun
updateMessage
(
streamedMessage
:
Message
)
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
)
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 {
...
@@ -105,4 +105,5 @@ interface ChatRoomView : LoadingView, MessageView {
* This user has joined the chat callback.
* This user has joined the chat callback.
*/
*/
fun
onJoined
()
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
...
@@ -24,10 +24,7 @@ import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.helper.KeyboardHelper
import
chat.rocket.android.helper.KeyboardHelper
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.widget.emoji.ComposerEditText
import
chat.rocket.android.widget.emoji.*
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.internal.realtime.State
import
chat.rocket.core.internal.realtime.State
import
dagger.android.support.AndroidSupportInjection
import
dagger.android.support.AndroidSupportInjection
import
io.reactivex.disposables.CompositeDisposable
import
io.reactivex.disposables.CompositeDisposable
...
@@ -64,7 +61,7 @@ private const val REQUEST_CODE_FOR_PERFORM_SAF = 42
...
@@ -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_LAST_SEEN
=
"chat_room_last_seen"
private
const
val
BUNDLE_CHAT_ROOM_IS_SUBSCRIBED
=
"chat_room_is_subscribed"
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
presenter
:
ChatRoomPresenter
@Inject
lateinit
var
parser
:
MessageParser
@Inject
lateinit
var
parser
:
MessageParser
private
lateinit
var
adapter
:
ChatRoomAdapter
private
lateinit
var
adapter
:
ChatRoomAdapter
...
@@ -187,7 +184,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
...
@@ -187,7 +184,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
activity
?.
apply
{
activity
?.
apply
{
if
(
recycler_view
.
adapter
==
null
)
{
if
(
recycler_view
.
adapter
==
null
)
{
adapter
=
ChatRoomAdapter
(
chatRoomType
,
chatRoomName
,
presenter
)
adapter
=
ChatRoomAdapter
(
chatRoomType
,
chatRoomName
,
presenter
,
reactionListener
=
this
@ChatRoomFragment
)
recycler_view
.
adapter
=
adapter
recycler_view
.
adapter
=
adapter
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
true
)
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
true
)
linearLayoutManager
.
stackFromEnd
=
true
linearLayoutManager
.
stackFromEnd
=
true
...
@@ -204,6 +202,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
...
@@ -204,6 +202,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
val
oldMessagesCount
=
adapter
.
itemCount
val
oldMessagesCount
=
adapter
.
itemCount
adapter
.
appendData
(
dataSet
)
adapter
.
appendData
(
dataSet
)
recycler_view
.
scrollToPosition
(
92
)
if
(
oldMessagesCount
==
0
&&
dataSet
.
isNotEmpty
())
{
if
(
oldMessagesCount
==
0
&&
dataSet
.
isNotEmpty
())
{
recycler_view
.
scrollToPosition
(
0
)
recycler_view
.
scrollToPosition
(
0
)
}
}
...
@@ -248,7 +247,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
...
@@ -248,7 +247,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
override
fun
dispatchUpdateMessage
(
index
:
Int
,
message
:
List
<
BaseViewModel
<*
>>)
{
override
fun
dispatchUpdateMessage
(
index
:
Int
,
message
:
List
<
BaseViewModel
<*
>>)
{
adapter
.
updateItem
(
message
.
last
())
adapter
.
updateItem
(
message
.
last
())
if
(
message
.
size
>
1
)
{
if
(
message
.
size
>
1
)
{
adapter
.
updateItem
(
message
.
last
())
adapter
.
prependData
(
listOf
(
message
.
first
()))
adapter
.
prependData
(
listOf
(
message
.
first
()))
}
}
}
}
...
@@ -317,6 +315,26 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
...
@@ -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
)
{
private
fun
setReactionButtonIcon
(
@DrawableRes
drawableId
:
Int
)
{
button_add_reaction
.
setImageResource
(
drawableId
)
button_add_reaction
.
setImageResource
(
drawableId
)
button_add_reaction
.
setTag
(
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(
...
@@ -10,8 +10,10 @@ data class AudioAttachmentViewModel(
override
val
messageId
:
String
,
override
val
messageId
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentTitle
:
CharSequence
,
override
val
attachmentTitle
:
CharSequence
,
override
val
id
:
Long
override
val
id
:
Long
,
)
:
BaseFileAttachmentViewModel
<
AudioAttachment
>
{
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseFileAttachmentViewModel
<
AudioAttachment
>
{
override
val
viewType
:
Int
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
AUDIO_ATTACHMENT
.
viewType
get
()
=
BaseViewModel
.
ViewType
.
AUDIO_ATTACHMENT
.
viewType
override
val
layoutId
:
Int
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> {
...
@@ -9,6 +9,8 @@ interface BaseViewModel<out T> {
val
messageId
:
String
val
messageId
:
String
val
viewType
:
Int
val
viewType
:
Int
val
layoutId
:
Int
val
layoutId
:
Int
var
reactions
:
List
<
ReactionViewModel
>
var
nextDownStreamMessage
:
BaseViewModel
<*>?
enum
class
ViewType
(
val
viewType
:
Int
)
{
enum
class
ViewType
(
val
viewType
:
Int
)
{
MESSAGE
(
0
),
MESSAGE
(
0
),
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ImageAttachmentViewModel.kt
View file @
fb5b651d
...
@@ -10,7 +10,9 @@ data class ImageAttachmentViewModel(
...
@@ -10,7 +10,9 @@ data class ImageAttachmentViewModel(
override
val
messageId
:
String
,
override
val
messageId
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentTitle
:
CharSequence
,
override
val
attachmentTitle
:
CharSequence
,
override
val
id
:
Long
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseFileAttachmentViewModel
<
ImageAttachment
>
{
)
:
BaseFileAttachmentViewModel
<
ImageAttachment
>
{
override
val
viewType
:
Int
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
IMAGE_ATTACHMENT
.
viewType
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(
...
@@ -12,6 +12,8 @@ data class MessageViewModel(
override
val
senderName
:
CharSequence
,
override
val
senderName
:
CharSequence
,
override
val
content
:
CharSequence
,
override
val
content
:
CharSequence
,
override
val
isPinned
:
Boolean
,
override
val
isPinned
:
Boolean
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
var
isFirstUnread
:
Boolean
var
isFirstUnread
:
Boolean
)
:
BaseMessageViewModel
<
Message
>
{
)
:
BaseMessageViewModel
<
Message
>
{
override
val
viewType
:
Int
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
...
@@ -5,13 +5,15 @@ import chat.rocket.core.model.Message
import
chat.rocket.core.model.url.Url
import
chat.rocket.core.model.url.Url
data class
UrlPreviewViewModel
(
data class
UrlPreviewViewModel
(
override
val
message
:
Message
,
override
val
message
:
Message
,
override
val
rawData
:
Url
,
override
val
rawData
:
Url
,
override
val
messageId
:
String
,
override
val
messageId
:
String
,
val
title
:
CharSequence
?,
val
title
:
CharSequence
?,
val
hostname
:
String
,
val
hostname
:
String
,
val
description
:
CharSequence
?,
val
description
:
CharSequence
?,
val
thumbUrl
:
String
?
val
thumbUrl
:
String
?,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseViewModel
<
Url
>
{
)
:
BaseViewModel
<
Url
>
{
override
val
viewType
:
Int
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
URL_PREVIEW
.
viewType
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(
...
@@ -10,7 +10,9 @@ data class VideoAttachmentViewModel(
override
val
messageId
:
String
,
override
val
messageId
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentUrl
:
String
,
override
val
attachmentTitle
:
CharSequence
,
override
val
attachmentTitle
:
CharSequence
,
override
val
id
:
Long
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
)
:
BaseFileAttachmentViewModel
<
VideoAttachment
>
{
)
:
BaseFileAttachmentViewModel
<
VideoAttachment
>
{
override
val
viewType
:
Int
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
VIDEO_ATTACHMENT
.
viewType
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
...
@@ -14,6 +14,7 @@ import chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.TokenRepository
import
chat.rocket.core.TokenRepository
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.MessageType
import
chat.rocket.core.model.MessageType
...
@@ -83,7 +84,8 @@ class ViewModelMapper @Inject constructor(private val context: Context,
...
@@ -83,7 +84,8 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
title
=
url
.
meta
?.
title
val
title
=
url
.
meta
?.
title
val
description
=
url
.
meta
?.
description
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
<
*
>?
{
private
fun
mapAttachment
(
message
:
Message
,
attachment
:
Attachment
):
BaseViewModel
<
*
>?
{
...
@@ -99,11 +101,11 @@ class ViewModelMapper @Inject constructor(private val context: Context,
...
@@ -99,11 +101,11 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
id
=
"${message.id}_${attachment.titleLink}"
.
hashCode
().
toLong
()
val
id
=
"${message.id}_${attachment.titleLink}"
.
hashCode
().
toLong
()
return
when
(
attachment
)
{
return
when
(
attachment
)
{
is
ImageAttachment
->
ImageAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
is
ImageAttachment
->
ImageAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
attachmentUrl
,
attachmentTitle
?:
""
,
id
)
attachmentUrl
,
attachmentTitle
?:
""
,
id
,
getReactions
(
message
)
)
is
VideoAttachment
->
VideoAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
is
VideoAttachment
->
VideoAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
attachmentUrl
,
attachmentTitle
?:
""
,
id
)
attachmentUrl
,
attachmentTitle
?:
""
,
id
,
getReactions
(
message
)
)
is
AudioAttachment
->
AudioAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
is
AudioAttachment
->
AudioAttachmentViewModel
(
message
,
attachment
,
message
.
id
,
attachmentUrl
,
attachmentTitle
?:
""
,
id
)
attachmentUrl
,
attachmentTitle
?:
""
,
id
,
getReactions
(
message
)
)
else
->
null
else
->
null
}
}
}
}
...
@@ -149,7 +151,27 @@ class ViewModelMapper @Inject constructor(private val context: Context,
...
@@ -149,7 +151,27 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
content
=
getContent
(
context
,
getMessageWithoutQuoteMarkdown
(
message
),
quote
)
val
content
=
getContent
(
context
,
getMessageWithoutQuoteMarkdown
(
message
),
quote
)
MessageViewModel
(
message
=
getMessageWithoutQuoteMarkdown
(
message
),
rawData
=
message
,
MessageViewModel
(
message
=
getMessageWithoutQuoteMarkdown
(
message
),
rawData
=
message
,
messageId
=
message
.
id
,
avatar
=
avatar
!!
,
time
=
time
,
senderName
=
sender
,
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
{
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
...
@@ -3,11 +3,9 @@ package chat.rocket.android.chatrooms.di
import
android.arch.lifecycle.LifecycleOwner
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.dagger.scope.PerFragment
import
dagger.Module
import
dagger.Module
import
dagger.Provides
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@Module
@PerFragment
@PerFragment
...
@@ -22,9 +20,4 @@ class ChatRoomsFragmentModule {
...
@@ -22,9 +20,4 @@ class ChatRoomsFragmentModule {
fun
provideLifecycleOwner
(
frag
:
ChatRoomsFragment
):
LifecycleOwner
{
fun
provideLifecycleOwner
(
frag
:
ChatRoomsFragment
):
LifecycleOwner
{
return
frag
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
package
chat.rocket.android.chatrooms.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
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.domain.*
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
...
@@ -24,7 +25,7 @@ import javax.inject.Inject
...
@@ -24,7 +25,7 @@ import javax.inject.Inject
class
ChatRoomsPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomsView
,
class
ChatRoomsPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomsView
,
private
val
strategy
:
CancelStrategy
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
ChatRooms
Navigator
,
private
val
navigator
:
Main
Navigator
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
getChatRoomsInteractor
:
GetChatRoomsInteractor
,
private
val
getChatRoomsInteractor
:
GetChatRoomsInteractor
,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
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
...
@@ -11,9 +11,7 @@ import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatroom.ui.PinnedMessagesActivity
import
chat.rocket.android.chatroom.ui.PinnedMessagesActivity
import
chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
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.dagger.scope.PerActivity
import
chat.rocket.android.main.di.MainActivityProvider
import
chat.rocket.android.main.di.MainModule
import
chat.rocket.android.main.di.MainModule
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.members.di.MembersFragmentProvider
import
chat.rocket.android.members.di.MembersFragmentProvider
...
@@ -37,8 +35,6 @@ abstract class ActivityBuilder {
...
@@ -37,8 +35,6 @@ abstract class ActivityBuilder {
@PerActivity
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
MainModule
::
class
,
@ContributesAndroidInjector
(
modules
=
[
MainModule
::
class
,
MainActivityProvider
::
class
,
ChatRoomsModule
::
class
,
ChatRoomsFragmentProvider
::
class
,
ChatRoomsFragmentProvider
::
class
,
ProfileFragmentProvider
::
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
package
chat.rocket.android.main.di
import
android.arch.lifecycle.LifecycleOwner
import
android.content.Context
import
android.content.Context
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerActivity
import
chat.rocket.android.dagger.scope.PerActivity
import
chat.rocket.android.main.presentation.MainNavigator
import
chat.rocket.android.main.presentation.MainNavigator
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.main.ui.MainActivity
import
dagger.Module
import
dagger.Module
import
dagger.Provides
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@Module
class
MainModule
{
class
MainModule
{
...
@@ -13,4 +17,13 @@ class MainModule {
...
@@ -13,4 +17,13 @@ class MainModule {
@Provides
@Provides
@PerActivity
@PerActivity
fun
provideMainNavigator
(
activity
:
MainActivity
,
context
:
Context
)
=
MainNavigator
(
activity
,
context
)
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
...
@@ -2,6 +2,7 @@ package chat.rocket.android.main.presentation
import
android.content.Context
import
android.content.Context
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.profile.ui.ProfileFragment
import
chat.rocket.android.profile.ui.ProfileFragment
...
@@ -27,4 +28,15 @@ class MainNavigator(internal val activity: MainActivity, internal val context: C
...
@@ -27,4 +28,15 @@ class MainNavigator(internal val activity: MainActivity, internal val context: C
SettingsFragment
.
newInstance
()
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
package
chat.rocket.android.main.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.realtime.disconnect
import
chat.rocket.core.internal.realtime.disconnect
import
chat.rocket.core.internal.rest.logout
import
chat.rocket.core.internal.rest.unregisterPushToken
import
chat.rocket.core.internal.rest.unregisterPushToken
import
timber.log.Timber
import
javax.inject.Inject
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
serverInteractor
:
GetCurrentServerInteractor
,
private
val
localRepository
:
LocalRepository
,
private
val
localRepository
:
LocalRepository
,
managerFactory
:
ConnectionManagerFactory
,
managerFactory
:
ConnectionManagerFactory
,
...
@@ -30,19 +35,21 @@ class MainPresenter @Inject constructor(private val navigator: MainNavigator,
...
@@ -30,19 +35,21 @@ class MainPresenter @Inject constructor(private val navigator: MainNavigator,
* Logout from current server.
* Logout from current server.
*/
*/
fun
logout
()
{
fun
logout
()
{
// TODO: inject CancelStrategy, and MainView.
launchUI
(
strategy
)
{
// launchUI(strategy) {
try
{
try
{
//
clearTokens()
clearTokens
()
//
client.logout()
client
.
logout
()
//TODO: Add the code to unsubscribe to all subscriptions.
//TODO: Add the code to unsubscribe to all subscriptions.
client
.
disconnect
()
client
.
disconnect
()
// view.onLogout()
view
.
onLogout
()
}
catch
(
e
:
RocketChatException
)
{
}
catch
(
exception
:
RocketChatException
)
{
Timber
.
e
(
e
)
exception
.
message
?.
let
{
// view.showMessage(e.message!!)
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
}
//
}
}
}
}
private
suspend
fun
clearTokens
()
{
private
suspend
fun
clearTokens
()
{
...
...
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
fb5b651d
package
chat.rocket.android.main.ui
package
chat.rocket.android.main.ui
import
android.app.Activity
import
android.content.Intent
import
android.content.Intent
import
android.os.Bundle
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v4.app.Fragment
...
@@ -7,25 +8,21 @@ import android.support.v7.app.AppCompatActivity
...
@@ -7,25 +8,21 @@ import android.support.v7.app.AppCompatActivity
import
android.view.Gravity
import
android.view.Gravity
import
android.view.MenuItem
import
android.view.MenuItem
import
chat.rocket.android.R
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.authentication.ui.AuthenticationActivity
import
chat.rocket.android.main.presentation.MainPresenter
import
chat.rocket.android.main.presentation.MainPresenter
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.util.extensions.showToast
import
chat.rocket.android.util.extensions.showToast
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
import
dagger.android.AndroidInjector
import
dagger.android.DispatchingAndroidInjector
import
dagger.android.DispatchingAndroidInjector
import
dagger.android.HasActivityInjector
import
dagger.android.support.HasSupportFragmentInjector
import
dagger.android.support.HasSupportFragmentInjector
import
kotlinx.android.synthetic.main.activity_main.*
import
kotlinx.android.synthetic.main.activity_main.*
import
kotlinx.android.synthetic.main.app_bar.*
import
kotlinx.android.synthetic.main.app_bar.*
import
javax.inject.Inject
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
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
@Inject
lateinit
var
presenter
:
MainPresenter
@Inject
lateinit
var
presenter
:
MainPresenter
private
var
isFragmentAdded
:
Boolean
=
false
private
var
isFragmentAdded
:
Boolean
=
false
...
@@ -68,6 +65,8 @@ class MainActivity : AppCompatActivity(), MainView, HasSupportFragmentInjector {
...
@@ -68,6 +65,8 @@ class MainActivity : AppCompatActivity(), MainView, HasSupportFragmentInjector {
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
activityInjector
():
AndroidInjector
<
Activity
>
=
activityDispatchingAndroidInjector
override
fun
supportFragmentInjector
():
AndroidInjector
<
Fragment
>
=
fragmentDispatchingAndroidInjector
override
fun
supportFragmentInjector
():
AndroidInjector
<
Fragment
>
=
fragmentDispatchingAndroidInjector
private
fun
setupToolbar
()
{
private
fun
setupToolbar
()
{
...
...
app/src/main/java/chat/rocket/android/profile/di/ProfileFragmentModule.kt
View file @
fb5b651d
package
chat.rocket.android.profile.di
package
chat.rocket.android.profile.di
import
android.arch.lifecycle.LifecycleOwner
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.profile.presentation.ProfileView
import
chat.rocket.android.profile.presentation.ProfileView
import
chat.rocket.android.profile.ui.ProfileFragment
import
chat.rocket.android.profile.ui.ProfileFragment
import
dagger.Module
import
dagger.Module
import
dagger.Provides
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@Module
@PerFragment
@PerFragment
...
@@ -22,9 +20,4 @@ class ProfileFragmentModule {
...
@@ -22,9 +20,4 @@ class ProfileFragmentModule {
fun
provideLifecycleOwner
(
frag
:
ProfileFragment
):
LifecycleOwner
{
fun
provideLifecycleOwner
(
frag
:
ProfileFragment
):
LifecycleOwner
{
return
frag
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
...
@@ -9,10 +9,10 @@ import android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
android.widget.TextView
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup.Listener
import
java.util.*
import
java.util.*
class
CategoryPagerAdapter
(
val
listener
:
Listener
)
:
PagerAdapter
()
{
class
CategoryPagerAdapter
(
val
listener
:
EmojiKeyboardListener
)
:
PagerAdapter
()
{
override
fun
isViewFromObject
(
view
:
View
,
obj
:
Any
):
Boolean
{
override
fun
isViewFromObject
(
view
:
View
,
obj
:
Any
):
Boolean
{
return
view
==
obj
return
view
==
obj
}
}
...
@@ -46,7 +46,7 @@ class CategoryPagerAdapter(val listener: Listener) : PagerAdapter() {
...
@@ -46,7 +46,7 @@ class CategoryPagerAdapter(val listener: Listener) : PagerAdapter() {
override
fun
getPageTitle
(
position
:
Int
)
=
EmojiCategory
.
values
()[
position
].
textIcon
()
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
>()
private
var
emojis
=
Collections
.
emptyList
<
Emoji
>()
fun
addEmojis
(
emojis
:
List
<
Emoji
>)
{
fun
addEmojis
(
emojis
:
List
<
Emoji
>)
{
...
@@ -66,7 +66,7 @@ class CategoryPagerAdapter(val listener: Listener) : PagerAdapter() {
...
@@ -66,7 +66,7 @@ class CategoryPagerAdapter(val listener: Listener) : PagerAdapter() {
override
fun
getItemCount
():
Int
=
emojis
.
size
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
)
private
val
emojiView
:
TextView
=
itemView
.
findViewById
(
R
.
id
.
emoji
)
fun
bind
(
emoji
:
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
...
@@ -21,14 +21,14 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
private
lateinit
var
searchView
:
View
private
lateinit
var
searchView
:
View
private
lateinit
var
backspaceView
:
View
private
lateinit
var
backspaceView
:
View
private
lateinit
var
parentContainer
:
ViewGroup
private
lateinit
var
parentContainer
:
ViewGroup
var
listener
:
Listener
?
=
null
var
listener
:
EmojiKeyboard
Listener
?
=
null
companion
object
{
companion
object
{
const
val
PREF_EMOJI_RECENTS
=
"PREF_EMOJI_RECENTS"
const
val
PREF_EMOJI_RECENTS
=
"PREF_EMOJI_RECENTS"
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
):
View
{
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
)
parentContainer
=
view
.
findViewById
(
R
.
id
.
emoji_keyboard_container
)
viewPager
=
view
.
findViewById
(
R
.
id
.
pager_categories
)
viewPager
=
view
.
findViewById
(
R
.
id
.
pager_categories
)
searchView
=
view
.
findViewById
(
R
.
id
.
emoji_search
)
searchView
=
view
.
findViewById
(
R
.
id
.
emoji_search
)
...
@@ -55,20 +55,17 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
...
@@ -55,20 +55,17 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
private
fun
setupViewPager
()
{
private
fun
setupViewPager
()
{
context
.
let
{
context
.
let
{
val
callback
=
when
(
it
)
{
val
callback
=
when
(
it
)
{
is
Listener
->
it
is
EmojiKeyboard
Listener
->
it
else
->
{
else
->
{
val
fragments
=
(
it
as
AppCompatActivity
).
supportFragmentManager
.
fragments
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"
)
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
)
{
override
fun
onEmojiAdded
(
emoji
:
Emoji
)
{
EmojiRepository
.
addToRecents
(
emoji
)
EmojiRepository
.
addToRecents
(
emoji
)
callback
.
onEmojiAdded
(
emoji
)
callback
.
onEmojiAdded
(
emoji
)
...
@@ -78,14 +75,14 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
...
@@ -78,14 +75,14 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
for
(
category
in
EmojiCategory
.
values
())
{
for
(
category
in
EmojiCategory
.
values
())
{
val
tab
=
tabLayout
.
getTabAt
(
category
.
ordinal
)
val
tab
=
tabLayout
.
getTabAt
(
category
.
ordinal
)
val
tabView
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
emoji_picker_tab
,
null
)
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
val
textView
=
tabView
.
findViewById
(
R
.
id
.
image_category
)
as
ImageView
textView
.
setImageResource
(
category
.
resourceIcon
())
textView
.
setImageResource
(
category
.
resourceIcon
())
}
}
val
currentTab
=
if
(
EmojiRepository
.
getRecents
().
isEmpty
())
EmojiCategory
.
PEOPLE
.
ordinal
else
val
currentTab
=
if
(
EmojiRepository
.
getRecents
().
isEmpty
())
EmojiCategory
.
PEOPLE
.
ordinal
else
EmojiCategory
.
RECENTS
.
ordinal
EmojiCategory
.
RECENTS
.
ordinal
viewPager
.
setCurrentItem
(
currentTab
)
viewPager
.
currentItem
=
currentTab
}
}
}
}
...
@@ -132,22 +129,4 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
...
@@ -132,22 +129,4 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
override
fun
onTextChanged
(
s
:
CharSequence
,
start
:
Int
,
before
:
Int
,
count
:
Int
)
{
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 @@
...
@@ -11,35 +11,18 @@
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"1dp"
android:layout_height=
"1dp"
android:background=
"@color/colorDividerMessageComposer"
android:background=
"@color/colorDividerMessageComposer"
app:layout_constraintBottom_toTopOf=
"@+id/
tabs
"
app:layout_constraintBottom_toTopOf=
"@+id/
picker_container
"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
app:layout_constraintTop_toTopOf=
"parent"
/>
<android.support.design.widget.TabLayout
<include
android:id=
"@+id/tabs"
android:id=
"@+id/picker_container"
android:layout_width=
"0dp"
layout=
"@layout/emoji_picker"
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"
app:layout_constraintBottom_toTopOf=
"@+id/emoji_actions_container"
app:layout_constraintBottom_toTopOf=
"@+id/emoji_actions_container"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_to
BottomOf=
"@+id/tabs
"
/>
app:layout_constraintTop_to
TopOf=
"parent
"
/>
<RelativeLayout
<RelativeLayout
android:id=
"@+id/emoji_actions_container"
android:id=
"@+id/emoji_actions_container"
...
@@ -60,8 +43,8 @@
...
@@ -60,8 +43,8 @@
android:clickable=
"true"
android:clickable=
"true"
android:focusable=
"true"
android:focusable=
"true"
android:padding=
"8dp"
android:padding=
"8dp"
android:
visibility=
"invisible
"
android:
src=
"@drawable/ic_search_gray_24px
"
android:
src=
"@drawable/ic_search_gray_24px
"
/>
android:
visibility=
"invisible
"
/>
<ImageView
<ImageView
android:id=
"@+id/emoji_backspace"
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 @@
...
@@ -74,11 +74,18 @@
style=
"@style/Message.TextView"
style=
"@style/Message.TextView"
android:layout_width=
"0dp"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"5dp"
android:layout_marginBottom=
"2dp"
android:layout_marginBottom=
"2dp"
android:layout_marginTop=
"5dp"
app:layout_constraintLeft_toLeftOf=
"@id/top_container"
app:layout_constraintLeft_toLeftOf=
"@id/top_container"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/top_container"
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!"
/>
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>
</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 @@
...
@@ -6,9 +6,9 @@
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:background=
"?android:attr/selectableItemBackground"
android:background=
"?android:attr/selectableItemBackground"
android:
paddingStart=
"72dp
"
android:
orientation=
"vertical
"
android:paddingEnd=
"@dimen/screen_edge_left_and_right_margins"
android:paddingEnd=
"@dimen/screen_edge_left_and_right_margins"
android:
orientation=
"vertical
"
>
android:
paddingStart=
"72dp
"
>
<com.facebook.drawee.view.SimpleDraweeView
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_attachment"
android:id=
"@+id/image_attachment"
...
@@ -39,4 +39,9 @@
...
@@ -39,4 +39,9 @@
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"Filename.png"
/>
tools:text=
"Filename.png"
/>
<include
layout=
"@layout/layout_reactions"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
</LinearLayout>
</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"?>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/url_preview_layout"
android:id=
"@+id/url_preview_layout"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:background=
"?android:attr/selectableItemBackground"
android:background=
"?android:attr/selectableItemBackground"
android:padding
Start=
"72
dp"
android:padding
End=
"24
dp"
android:padding
End=
"24
dp"
>
android:padding
Start=
"72
dp"
>
<com.facebook.drawee.view.SimpleDraweeView
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_preview"
android:id=
"@+id/image_preview"
android:layout_width=
"70dp"
android:layout_width=
"70dp"
android:layout_height=
"50dp"
android:layout_height=
"50dp"
app:actualImageScaleType=
"centerCrop"
/>
app:actualImageScaleType=
"centerCrop"
/>
<TextView
<TextView
android:id=
"@+id/text_host"
android:id=
"@+id/text_host"
...
@@ -22,26 +21,33 @@
...
@@ -22,26 +21,33 @@
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginStart=
"8dp"
android:textColor=
"@color/colorSecondaryText"
android:textColor=
"@color/colorSecondaryText"
tools:text=
"www.uol.com.br"
app:layout_constraintEnd_toEndOf=
"parent"
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
<TextView
android:id=
"@+id/text_title"
android:id=
"@+id/text_title"
android:layout_width=
"0dp"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:textColor=
"@color/colorAccent"
android:textColor=
"@color/colorAccent"
tools:text=
"Web page title"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"@+id/text_host"
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
<TextView
android:id=
"@+id/text_description"
android:id=
"@+id/text_description"
android:layout_width=
"0dp"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"description"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"@+id/text_host"
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>
</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 @@
...
@@ -22,6 +22,11 @@
android:icon=
"@drawable/ic_content_copy_black_24px"
android:icon=
"@drawable/ic_content_copy_black_24px"
android:title=
"@string/action_msg_copy"
/>
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-->
<!--<item-->
<!--android:id="@+id/action_menu_msg_share"-->
<!--android:id="@+id/action_menu_msg_share"-->
<!--andrtextIconicon="@drawable/ic_share_black_24px"-->
<!--andrtextIconicon="@drawable/ic_share_black_24px"-->
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
fb5b651d
...
@@ -87,10 +87,11 @@
...
@@ -87,10 +87,11 @@
<string
name=
"action_msg_quote"
>
Citar
</string>
<string
name=
"action_msg_quote"
>
Citar
</string>
<string
name=
"action_msg_delete"
>
Remover
</string>
<string
name=
"action_msg_delete"
>
Remover
</string>
<string
name=
"action_msg_pin"
>
Fixar Mensagem
</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_star"
>
Favoritar Mensagem
</string>
<string
name=
"action_msg_share"
>
Compartilhar
</string>
<string
name=
"action_msg_share"
>
Compartilhar
</string>
<string
name=
"action_title_editing"
>
Editando Mensagem
</string>
<string
name=
"action_title_editing"
>
Editando Mensagem
</string>
<string
name=
"action_msg_add_reaction"
>
Adicionar reação
</string>
<!-- Permission messages -->
<!-- Permission messages -->
<string
name=
"permission_editing_not_allowed"
>
Edição não permitida
</string>
<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 @@
...
@@ -24,6 +24,8 @@
<!-- Emoji -->
<!-- Emoji -->
<dimen
name=
"picker_padding_bottom"
>
16dp
</dimen>
<dimen
name=
"picker_padding_bottom"
>
16dp
</dimen>
<dimen
name=
"supposed_keyboard_height"
>
252dp
</dimen>
<dimen
name=
"supposed_keyboard_height"
>
252dp
</dimen>
<dimen
name=
"picker_popup_height"
>
250dp
</dimen>
<dimen
name=
"picker_popup_width"
>
300dp
</dimen>
<!-- Message -->
<!-- Message -->
<dimen
name=
"padding_quote"
>
8dp
</dimen>
<dimen
name=
"padding_quote"
>
8dp
</dimen>
...
...
app/src/main/res/values/strings.xml
View file @
fb5b651d
...
@@ -92,6 +92,7 @@
...
@@ -92,6 +92,7 @@
<string
name=
"action_msg_star"
>
Star Message
</string>
<string
name=
"action_msg_star"
>
Star Message
</string>
<string
name=
"action_msg_share"
>
Share
</string>
<string
name=
"action_msg_share"
>
Share
</string>
<string
name=
"action_title_editing"
>
Editing Message
</string>
<string
name=
"action_title_editing"
>
Editing Message
</string>
<string
name=
"action_msg_add_reaction"
>
Add reaction
</string>
<!-- Permission messages -->
<!-- Permission messages -->
<string
name=
"permission_editing_not_allowed"
>
Editing is not allowed
</string>
<string
name=
"permission_editing_not_allowed"
>
Editing is not allowed
</string>
...
...
dependencies.gradle
View file @
fb5b651d
...
@@ -30,6 +30,7 @@ ext {
...
@@ -30,6 +30,7 @@ ext {
markwon
:
'1.0.3'
,
markwon
:
'1.0.3'
,
sheetMenu
:
'1.3.3'
,
sheetMenu
:
'1.3.3'
,
aVLoadingIndicatorView
:
'2.1.3'
,
aVLoadingIndicatorView
:
'2.1.3'
,
flexbox
:
'0.3.2'
,
// For testing
// For testing
junit
:
'4.12'
,
junit
:
'4.12'
,
...
@@ -49,6 +50,7 @@ ext {
...
@@ -49,6 +50,7 @@ ext {
design
:
"com.android.support:design:${versions.support}"
,
design
:
"com.android.support:design:${versions.support}"
,
constraintLayout
:
"com.android.support.constraint:constraint-layout:${versions.constraintLayout}"
,
constraintLayout
:
"com.android.support.constraint:constraint-layout:${versions.constraintLayout}"
,
cardView
:
"com.android.support:cardview-v7:${versions.support}"
,
cardView
:
"com.android.support:cardview-v7:${versions.support}"
,
flexbox
:
"com.google.android:flexbox:${versions.flexbox}"
,
androidKtx
:
"androidx.core:core-ktx:${versions.androidKtx}"
,
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