mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-14 02:01:56 +00:00
added the intro message.
there is still a bug that on entering the chat dialog, and on refreshing, the chat scroll moves to the bottom instead of to the top
This commit is contained in:
parent
76038e7bfa
commit
75b6167565
5 changed files with 172 additions and 32 deletions
80
Habitica/res/layout/tavern_chat_intro_item.xml
Normal file
80
Habitica/res/layout/tavern_chat_intro_item.xml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="87dp"
|
||||
android:layout_height="69dp"
|
||||
android:layout_gravity="center_horizontal|top"
|
||||
android:visibility="visible"
|
||||
app:showBackground="false"
|
||||
app:showMount="false"
|
||||
app:showPet="false"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/filler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="16dp"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/gray_300"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.habitrpg.android.habitica.ui.views.social.UsernameLabel
|
||||
android:id="@+id/display_name_textview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="24dp"
|
||||
android:baselineAligned="false"
|
||||
android:clipToPadding="false"
|
||||
android:textAlignment="center"
|
||||
android:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subline_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/gray_300"
|
||||
android:textSize="12sp"
|
||||
tools:text="@Username" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/Filler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/gray_300"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.habitrpg.android.habitica.ui.views.HabiticaEmojiTextView
|
||||
android:id="@+id/message_text"
|
||||
android:layout_width="348dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:lineSpacingMultiplier="1.0"
|
||||
android:text="Start chatting below! Remember to be friendly and follow the Community Guidelines."
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/gray_300"
|
||||
tools:text="Start chatting below! Remember to be friendly and follow the Community Guidelines." />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -9,7 +9,7 @@ import com.habitrpg.android.habitica.extensions.inflate
|
|||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.ChatRecyclerViewHolder
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.ChatRecyclerMessageViewHolder
|
||||
import io.reactivex.BackpressureStrategy
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
|
|
@ -40,7 +40,7 @@ class ChatRecyclerViewAdapter(data: OrderedRealmCollection<ChatMessage>?, autoUp
|
|||
return if (viewType == 0) {
|
||||
SystemChatMessageViewHolder(parent.inflate(R.layout.system_chat_message))
|
||||
} else {
|
||||
ChatRecyclerViewHolder(parent.inflate(R.layout.tavern_chat_item), uuid, isTavern)
|
||||
ChatRecyclerMessageViewHolder(parent.inflate(R.layout.tavern_chat_item), uuid, isTavern)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ class ChatRecyclerViewAdapter(data: OrderedRealmCollection<ChatMessage>?, autoUp
|
|||
if (data[position].isSystemMessage) {
|
||||
(holder as? SystemChatMessageViewHolder)?.bind(data[position])
|
||||
} else {
|
||||
val chatHolder = holder as? ChatRecyclerViewHolder ?: return
|
||||
val chatHolder = holder as? ChatRecyclerMessageViewHolder ?: return
|
||||
val message = data[position]
|
||||
chatHolder.bind(message,
|
||||
uuid,
|
||||
|
|
|
|||
|
|
@ -8,11 +8,14 @@ import com.habitrpg.android.habitica.extensions.inflate
|
|||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.ChatRecyclerViewHolder
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.ChatRecyclerIntroViewHolder
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.ChatRecyclerMessageViewHolder
|
||||
import io.reactivex.BackpressureStrategy
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
|
||||
class InboxAdapter(private var user: User?) : PagedListAdapter<ChatMessage, ChatRecyclerViewHolder>(DIFF_CALLBACK) {
|
||||
class InboxAdapter(private var user: User?, private var replyToUser : Member) : PagedListAdapter<ChatMessage, ChatRecyclerViewHolder>(DIFF_CALLBACK) {
|
||||
private var expandedMessageId: String? = null
|
||||
|
||||
private val likeMessageEvents = PublishSubject.create<ChatMessage>()
|
||||
|
|
@ -22,24 +25,49 @@ class InboxAdapter(private var user: User?) : PagedListAdapter<ChatMessage, Chat
|
|||
private val replyMessageEvents = PublishSubject.create<String>()
|
||||
private val copyMessageEvents = PublishSubject.create<ChatMessage>()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatRecyclerViewHolder {
|
||||
return ChatRecyclerViewHolder(parent.inflate(R.layout.tavern_chat_item), user?.id ?: "", false)
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return when (position == super.getItemCount()) {
|
||||
true -> 1
|
||||
false -> 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ChatRecyclerViewHolder, position: Int) {
|
||||
val message = getItem(position) ?: return
|
||||
override fun getItemCount(): Int {
|
||||
return super.getItemCount() + 1
|
||||
}
|
||||
|
||||
holder.bind(message,
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatRecyclerViewHolder {
|
||||
return if (viewType == 1) ChatRecyclerIntroViewHolder(parent.inflate(R.layout.tavern_chat_intro_item), replyToUser.id!!)
|
||||
else ChatRecyclerMessageViewHolder(parent.inflate(R.layout.tavern_chat_item), user?.id ?: "", false)
|
||||
}
|
||||
|
||||
fun getFirstMessage() : ChatMessage
|
||||
{
|
||||
var firstMessage = ChatMessage()
|
||||
return firstMessage
|
||||
}
|
||||
override fun onBindViewHolder(holder: ChatRecyclerViewHolder, position: Int) {
|
||||
val firstMessage : Boolean = getItemViewType(position) == 1
|
||||
if (firstMessage) {
|
||||
val introHolder = holder as ChatRecyclerIntroViewHolder
|
||||
introHolder.bind(replyToUser)
|
||||
introHolder.onOpenProfile = { userLabelClickEvents.onNext(it) }
|
||||
}
|
||||
else {
|
||||
val message : ChatMessage = getItem(position) ?: return
|
||||
val messageHolder = holder as ChatRecyclerMessageViewHolder
|
||||
messageHolder.bind(message,
|
||||
user?.id ?: "",
|
||||
user,
|
||||
expandedMessageId == message.id)
|
||||
holder.onShouldExpand = { expandMessage(message.id, position) }
|
||||
holder.onLikeMessage = { likeMessageEvents.onNext(it) }
|
||||
holder.onOpenProfile = { userLabelClickEvents.onNext(it) }
|
||||
holder.onReply = { replyMessageEvents.onNext(it) }
|
||||
holder.onCopyMessage = { copyMessageEvents.onNext(it) }
|
||||
holder.onFlagMessage = { flagMessageEvents.onNext(it) }
|
||||
holder.onDeleteMessage = { deleteMessageEvents.onNext(it) }
|
||||
messageHolder.onShouldExpand = { expandMessage(message.id, position) }
|
||||
messageHolder.onLikeMessage = { likeMessageEvents.onNext(it) }
|
||||
messageHolder.onOpenProfile = { userLabelClickEvents.onNext(it) }
|
||||
messageHolder.onReply = { replyMessageEvents.onNext(it) }
|
||||
messageHolder.onCopyMessage = { copyMessageEvents.onNext(it) }
|
||||
messageHolder.onFlagMessage = { flagMessageEvents.onNext(it) }
|
||||
messageHolder.onDeleteMessage = { deleteMessageEvents.onNext(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun getLikeMessageFlowable(): Flowable<ChatMessage> {
|
||||
|
|
|
|||
|
|
@ -68,21 +68,25 @@ class InboxMessageListFragment : BaseMainFragment(), androidx.swiperefreshlayout
|
|||
val layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this.getActivity())
|
||||
recyclerView.layoutManager = layoutManager
|
||||
|
||||
chatAdapter = InboxAdapter(user)
|
||||
viewModel?.messages?.observe(this.viewLifecycleOwner, Observer { chatAdapter?.submitList(it) })
|
||||
viewModel?.getMemberData()?.observe(this.viewLifecycleOwner, Observer {
|
||||
activity?.binding?.toolbarTitle?.text = it?.profile?.name
|
||||
})
|
||||
recyclerView.adapter = chatAdapter
|
||||
recyclerView.itemAnimator = SafeDefaultItemAnimator()
|
||||
chatAdapter?.let { adapter ->
|
||||
compositeSubscription.add(adapter.getUserLabelClickFlowable().subscribe(Consumer<String> {
|
||||
FullProfileActivity.open(it)
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getDeleteMessageFlowable().subscribe(Consumer { this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getFlagMessageClickFlowable().subscribe(Consumer { this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getCopyMessageFlowable().subscribe(Consumer { this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
compositeSubscription.add(apiClient.getMember(replyToUserUUID!!).subscribe( Consumer
|
||||
{ member ->
|
||||
chatAdapter = InboxAdapter(user, member)
|
||||
viewModel?.messages?.observe(this.viewLifecycleOwner, Observer { chatAdapter?.submitList(it) })
|
||||
|
||||
viewModel?.getMemberData()?.observe(this.viewLifecycleOwner, Observer {
|
||||
activity?.binding?.toolbarTitle?.text = it?.profile?.name
|
||||
})
|
||||
recyclerView.adapter = chatAdapter
|
||||
recyclerView.itemAnimator = SafeDefaultItemAnimator()
|
||||
chatAdapter?.let { adapter ->
|
||||
compositeSubscription.add(adapter.getUserLabelClickFlowable().subscribe(Consumer<String> {
|
||||
FullProfileActivity.open(it)
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getDeleteMessageFlowable().subscribe(Consumer { this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getFlagMessageClickFlowable().subscribe(Consumer { this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getCopyMessageFlowable().subscribe(Consumer { this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
}))
|
||||
|
||||
chatBarView.sendAction = { sendMessage(it) }
|
||||
chatBarView.maxChatLength = configManager.maxChatLength()
|
||||
|
|
|
|||
|
|
@ -28,8 +28,36 @@ import com.habitrpg.android.habitica.ui.views.social.UsernameLabel
|
|||
import io.reactivex.Maybe
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
|
||||
class ChatRecyclerViewHolder(itemView: View, private var userId: String, private val isTavern: Boolean) : RecyclerView.ViewHolder(itemView) {
|
||||
open class ChatRecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
}
|
||||
|
||||
class ChatRecyclerIntroViewHolder(itemView: View, replyToUUID: String) : ChatRecyclerViewHolder(itemView) {
|
||||
private val avatarView: AvatarView by bindView(R.id.avatar_view)
|
||||
private val displayNameView: UsernameLabel by bindView(R.id.display_name_textview)
|
||||
private val sublineTextView: TextView by bindView(R.id.subline_textview)
|
||||
private val messageText: HabiticaEmojiTextView by bindView(R.id.message_text)
|
||||
|
||||
var onOpenProfile: ((String) -> Unit)? = null
|
||||
|
||||
init {
|
||||
avatarView.setOnClickListener { onOpenProfile?.invoke(replyToUUID) }
|
||||
displayNameView.setOnClickListener { onOpenProfile?.invoke(replyToUUID) }
|
||||
sublineTextView.setOnClickListener { onOpenProfile?.invoke(replyToUUID) }
|
||||
}
|
||||
|
||||
fun bind(member: Member) {
|
||||
avatarView.setAvatar(member)
|
||||
displayNameView.username = member.displayName
|
||||
displayNameView.tier = member.contributor?.level ?: 0
|
||||
sublineTextView.text = "@" + member.username
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ChatRecyclerMessageViewHolder(itemView: View, private var userId: String, private val isTavern: Boolean) : ChatRecyclerViewHolder(itemView) {
|
||||
|
||||
private val messageWrapper: ViewGroup by bindView(R.id.message_wrapper)
|
||||
private val avatarView: AvatarView by bindView(R.id.avatar_view)
|
||||
|
|
|
|||
Loading…
Reference in a new issue