ChatMessageAdapter.kt (4888B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2021--2025 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 /* 21 * @author t3sserakt 22 * @file GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/adapters/ChatMessageAdapter.kt 23 */ 24 25 26 package org.gnunet.gnunetmessenger.ui.adapters 27 28 29 30 import android.view.LayoutInflater 31 import android.view.View 32 import android.view.ViewGroup 33 import android.widget.TextView 34 import androidx.recyclerview.widget.DiffUtil 35 import androidx.recyclerview.widget.ListAdapter 36 import androidx.recyclerview.widget.RecyclerView 37 import org.gnunet.gnunetmessenger.R 38 import org.gnunet.gnunetmessenger.model.ChatMessage 39 import org.gnunet.gnunetmessenger.model.ChatMessageType 40 import java.text.SimpleDateFormat 41 import java.util.Locale 42 import java.util.Date 43 44 class ChatMessageAdapter : ListAdapter<ChatMessage, RecyclerView.ViewHolder>(DiffCallback()) { 45 46 companion object { 47 private const val VIEW_TYPE_OWN = 1 48 private const val VIEW_TYPE_OTHER = 2 49 private const val VIEW_TYPE_SYSTEM = 3 50 } 51 52 override fun getItemViewType(position: Int): Int { 53 return when (getItem(position).type) { 54 ChatMessageType.OWN -> VIEW_TYPE_OWN 55 ChatMessageType.OTHER -> VIEW_TYPE_OTHER 56 ChatMessageType.SYSTEM -> VIEW_TYPE_SYSTEM 57 else -> VIEW_TYPE_SYSTEM 58 } 59 } 60 61 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { 62 val inflater = LayoutInflater.from(parent.context) 63 return when (viewType) { 64 VIEW_TYPE_OWN -> { 65 val view = inflater.inflate(R.layout.item_message_own, parent, false) 66 OwnMessageViewHolder(view) 67 } 68 VIEW_TYPE_OTHER -> { 69 val view = inflater.inflate(R.layout.item_message_other, parent, false) 70 OtherMessageViewHolder(view) 71 } 72 VIEW_TYPE_SYSTEM -> { 73 val view = inflater.inflate(R.layout.item_message_system, parent, false) 74 SystemMessageViewHolder(view) 75 } 76 else -> throw IllegalArgumentException("Unknown view type $viewType") 77 } 78 } 79 80 override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { 81 val message = getItem(position) 82 when (holder) { 83 is OwnMessageViewHolder -> holder.bind(message) 84 is OtherMessageViewHolder -> holder.bind(message) 85 is SystemMessageViewHolder -> holder.bind(message) 86 } 87 } 88 89 class OwnMessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 90 fun bind(message: ChatMessage) { 91 itemView.findViewById<TextView>(R.id.messageText).text = message.text 92 itemView.findViewById<TextView>(R.id.timestamp).text = formatTime(message.timestamp) 93 } 94 } 95 96 class OtherMessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 97 fun bind(message: ChatMessage) { 98 itemView.findViewById<TextView>(R.id.messageText).text = message.text 99 itemView.findViewById<TextView>(R.id.senderName).text = message.sender?.name 100 itemView.findViewById<TextView>(R.id.timestamp).text = formatTime(message.timestamp) 101 } 102 } 103 104 class SystemMessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 105 fun bind(message: ChatMessage) { 106 itemView.findViewById<TextView>(R.id.messageText).text = message.text 107 itemView.findViewById<TextView>(R.id.timestamp).text = formatTime(message.timestamp) 108 } 109 } 110 111 class DiffCallback : DiffUtil.ItemCallback<ChatMessage>() { 112 override fun areItemsTheSame(oldItem: ChatMessage, newItem: ChatMessage): Boolean { 113 return oldItem.text == newItem.text && 114 oldItem.sender == newItem.sender && 115 oldItem.timestamp == newItem.timestamp 116 } 117 118 override fun areContentsTheSame(oldItem: ChatMessage, newItem: ChatMessage): Boolean { 119 return oldItem == newItem 120 } 121 } 122 } 123 124 fun formatTime(timestamp: Long): String { 125 val sdf = SimpleDateFormat("HH:mm", Locale.getDefault()) 126 return sdf.format(Date(timestamp)) 127 }