Commit b74ee777 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Add mention list feature.

parent 590aedde
......@@ -14,6 +14,12 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
}
}
fun toMentions(chatRoomId: String) {
activity.addFragmentBackStack("MentionsFragment", R.id.fragment_container) {
chat.rocket.android.mentions.ui.newInstance(chatRoomId)
}
}
fun toPinnedMessageList(chatRoomId: String) {
activity.addFragmentBackStack("PinnedMessages", R.id.fragment_container) {
chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId)
......
......@@ -713,6 +713,9 @@ class ChatRoomPresenter @Inject constructor(
fun toMembersList(chatRoomId: String) =
navigator.toMembersList(chatRoomId)
fun toMentions(chatRoomId: String) =
navigator.toMentions(chatRoomId)
fun toPinnedMessageList(chatRoomId: String) =
navigator.toPinnedMessageList(chatRoomId)
......
......@@ -216,6 +216,9 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
R.id.action_members_list -> {
presenter.toMembersList(chatRoomId)
}
R.id.action_mentions -> {
presenter.toMentions(chatRoomId)
}
R.id.action_pinned_messages -> {
presenter.toPinnedMessageList(chatRoomId)
}
......
......@@ -19,6 +19,7 @@ import chat.rocket.android.files.di.FilesFragmentProvider
import chat.rocket.android.main.di.MainModule
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.members.di.MembersFragmentProvider
import chat.rocket.android.mentions.di.MentionsFragmentProvider
import chat.rocket.android.pinnedmessages.di.PinnedMessagesFragmentProvider
import chat.rocket.android.profile.di.ProfileFragmentProvider
import chat.rocket.android.server.di.ChangeServerModule
......@@ -62,6 +63,7 @@ abstract class ActivityBuilder {
ChatRoomModule::class,
ChatRoomFragmentProvider::class,
MembersFragmentProvider::class,
MentionsFragmentProvider::class,
PinnedMessagesFragmentProvider::class,
FavoriteMessagesFragmentProvider::class,
FilesFragmentProvider::class
......
......@@ -8,7 +8,7 @@ import chat.rocket.android.files.uimodel.FileUiModel
interface FilesView : MessageView, LoadingView {
/**
* Show list of files for the current room.
* Shows the list of files for the current room.
*
* @param dataSet The data set to show.
* @param total The total number of files.
......
package chat.rocket.android.mentions.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.mentions.presentention.MentionsView
import chat.rocket.android.mentions.ui.MentionsFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class MentionsFragmentModule {
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: MentionsFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
@Provides
@PerFragment
fun provideMentionsView(frag: MentionsFragment): MentionsView {
return frag
}
}
\ No newline at end of file
package chat.rocket.android.mentions.di
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.mentions.ui.MentionsFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class MentionsFragmentProvider {
@ContributesAndroidInjector(modules = [MentionsFragmentModule::class])
@PerFragment
abstract fun provideMentionsFragment(): MentionsFragment
}
\ No newline at end of file
package chat.rocket.android.mentions.presentention
import chat.rocket.android.chatroom.uimodel.UiModelMapper
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.server.domain.ChatRoomsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extensions.launchUI
import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.rest.getMentions
import timber.log.Timber
import javax.inject.Inject
class MentionsPresenter @Inject constructor(
private val view: MentionsView,
private val strategy: CancelStrategy,
private val roomsInteractor: ChatRoomsInteractor,
private val mapper: UiModelMapper,
val serverInteractor: GetCurrentServerInteractor,
val factory: RocketChatClientFactory
) {
private val serverUrl = serverInteractor.get()!!
private val client = factory.create(serverUrl)
private var offset: Long = 0
/**
* Loads all mentions for the given room id.
*
* @param roomId The id of the room to get the mentions from.
*/
fun loadMentions(roomId: String) {
launchUI(strategy) {
try {
view.showLoading()
roomsInteractor.getById(serverUrl, roomId)?.let {
val mentions = client.getMentions(roomId, it.type, offset, 30)
val mentionsList = mapper.map(mentions.result, asNotReversed = true)
view.showMentions(mentionsList)
offset += 1 * 30
}.ifNull {
Timber.e("Couldn't find a room with id: $roomId at current server.")
}
} catch (exception: RocketChatException) {
Timber.e(exception)
} finally {
view.hideLoading()
}
}
}
}
\ No newline at end of file
package chat.rocket.android.mentions.presentention
import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
interface MentionsView : MessageView, LoadingView {
/**
* Shows the list of mentions for the current room.
*
* @param mentions The list of mentions.
*/
fun showMentions(mentions: List<BaseUiModel<*>>)
}
\ No newline at end of file
package chat.rocket.android.mentions.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.mentions.presentention.MentionsPresenter
import chat.rocket.android.mentions.presentention.MentionsView
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_mentions.*
import javax.inject.Inject
fun newInstance(chatRoomId: String): Fragment {
return MentionsFragment().apply {
arguments = Bundle(1).apply {
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
}
}
}
private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id"
class MentionsFragment : Fragment(), MentionsView {
private lateinit var chatRoomId: String
private lateinit var adapter: ChatRoomAdapter
@Inject
lateinit var presenter: MentionsPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
val bundle = arguments
if (bundle != null) {
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID)
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_mentions)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
presenter.loadMentions(chatRoomId)
}
override fun showMentions(mentions: List<BaseUiModel<*>>) {
ui {
if (recycler_view.adapter == null) {
adapter = ChatRoomAdapter(enableActions = false)
recycler_view.adapter = adapter
val linearLayoutManager = LinearLayoutManager(context)
recycler_view.layoutManager = linearLayoutManager
recycler_view.itemAnimator = DefaultItemAnimator()
if (mentions.size >= 30) {
recycler_view.addOnScrollListener(object :
EndlessRecyclerViewScrollListener(linearLayoutManager) {
override fun onLoadMore(
page: Int,
totalItemsCount: Int,
recyclerView: RecyclerView
) {
presenter.loadMentions(chatRoomId)
}
})
}
group_no_mention.isVisible = mentions.isEmpty()
}
adapter.appendData(mentions)
}
}
override fun showMessage(resId: Int) {
ui {
showToast(resId)
}
}
override fun showMessage(message: String) {
ui {
showToast(message)
}
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun showLoading() {
ui { view_loading.isVisible = true }
}
override fun hideLoading() {
ui { view_loading.isVisible = false }
}
private fun setupToolbar() {
(activity as ChatRoomActivity).let {
it.showToolbarTitle(getString(R.string.msg_mentions))
it.hideToolbarChatRoomIcon()
}
}
}
\ No newline at end of file
package chat.rocket.android.chatroom.di
package chat.rocket.android.pinnedmessages.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
......
package chat.rocket.android.pinnedmessages.di
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.chatroom.di.PinnedMessagesFragmentModule
import chat.rocket.android.pinnedmessages.ui.PinnedMessagesFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mentions.ui.MentionsFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:indicatorColor="@color/colorBlack"
app:indicatorName="BallPulseIndicator"
app:layout_constraintBottom_toBottomOf="@+id/recycler_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/image_mention"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/ic_at_black_24dp"
android:tint="@color/icon_grey"
app:layout_constraintBottom_toTopOf="@+id/text_no_mention"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/text_no_mention"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/msg_no_mention"
android:textColor="@color/colorSecondaryText"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/text_all_mentions_appear_here"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_mention" />
<TextView
android:id="@+id/text_all_mentions_appear_here"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/msg_all_the_mentions_appear_here"
android:textAlignment="center"
android:textColor="@color/colorSecondaryTextLight"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_no_mention" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_no_mention"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="image_mention,text_no_mention,text_all_mentions_appear_here"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -7,6 +7,11 @@
android:title="@string/title_members_list"
app:showAsAction="never" />
<item
android:id="@+id/action_mentions"
android:title="@string/msg_mentions"
app:showAsAction="never" />
<item
android:id="@+id/action_pinned_messages"
android:title="@string/title_pinned_messages"
......
......@@ -191,6 +191,12 @@
<!-- Members List -->
<string name="title_members_list">Miembros</string>
<!-- Mentions -->
<!-- TODO Add proper translation-->
<string name="msg_mentions">Mentions</string>
<string name="msg_no_mention">No mention</string>
<string name="msg_all_the_mentions_appear_here">All the mentions\nappear here</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">Mensajes fijados</string>
<string name="no_pinned_messages">Sin mensajes fijadas</string>
......
......@@ -192,6 +192,12 @@
<!-- Members List -->
<string name="title_members_list">Membres</string>
<!-- Mentions -->
<!-- TODO Add proper translation-->
<string name="msg_mentions">Mentions</string>
<string name="msg_no_mention">No mention</string>
<string name="msg_all_the_mentions_appear_here">All the mentions\nappear here</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">Messages épinglés</string>
<string name="no_pinned_messages">Aucun message épinglé</string>
......
......@@ -178,6 +178,12 @@
<!-- Members List -->
<string name="title_members_list">सदस्य</string>
<!-- Mentions -->
<!-- TODO Add proper translation-->
<string name="msg_mentions">Mentions</string>
<string name="msg_no_mention">No mention</string>
<string name="msg_all_the_mentions_appear_here">All the mentions\nappear here</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">पिन किए गए संदेश</string>
<string name="no_pinned_messages">कोई पिन संदेश नहीं</string>
......
......@@ -175,21 +175,26 @@
<!-- Members List -->
<string name="title_members_list">Membros</string>
<!-- Mentions -->
<string name="msg_mentions">Menções</string>
<string name="msg_no_mention">Nenhuma menção</string>
<string name="msg_all_the_mentions_appear_here">Todas menções\naparecerão aqui</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">Mensagens Pinadas</string>
<string name="no_pinned_messages">Nenhuma mensagem pinada</string>
<string name="no_pinned_description">Todas as mensagens pinadas\naparecerão aqui</string>
<string name="no_pinned_description">Todas mensagens pinadas\naparecerão aqui</string>
<!-- Favorite Messages -->
<string name="title_favorite_messages">Messagens Favoritas</string>
<string name="no_favorite_messages">Nenhuma messagem favorita</string>
<string name="no_favorite_description">Todas as mensagens favoritas\naparecerão aqui</string>
<string name="no_favorite_description">Todas mensagens favoritas\naparecerão aqui</string>
<!-- Files -->
<string name="msg_files">Arquivos</string>
<string name="title_files_total">Arquivos (%d)</string>
<string name="msg_no_files">Nenhum arquivo</string>
<string name="msg_all_files_appear_here">Todos os arquivos aparecerão aqui</string>
<string name="msg_all_files_appear_here">Todos arquivos aparecerão aqui</string>
<!-- Upload Messages -->
<string name="max_file_size_exceeded">Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)</string>
......
......@@ -174,6 +174,12 @@
<!-- Members List -->
<string name="title_members_list">Пользователи</string>
<!-- Mentions -->
<!-- TODO Add proper translation-->
<string name="msg_mentions">Mentions</string>
<string name="msg_no_mention">No mention</string>
<string name="msg_all_the_mentions_appear_here">All the mentions\nappear here</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">Прикрепленные сообщения</string>
<string name="no_pinned_messages">Нет прикрепленных сообщений</string>
......
......@@ -174,6 +174,11 @@
<!-- Members List -->
<string name="title_members_list">Members</string>
<!-- Mentions -->
<string name="msg_mentions">Mentions</string>
<string name="msg_no_mention">No mention</string>
<string name="msg_all_the_mentions_appear_here">All the mentions\nappear here</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">Pinned Messages</string>
<string name="no_pinned_messages">No pinned messages</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment