package com.geeksville.mesh.ui import android.content.Context import android.text.SpannedString import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.core.content.ContextCompat import androidx.core.text.toSpannable import androidx.recyclerview.widget.RecyclerView import com.geeksville.mesh.R import com.geeksville.mesh.database.entity.MeshLog import java.text.DateFormat import java.util.Date class DebugAdapter internal constructor( context: Context ) : RecyclerView.Adapter() { private val inflater: LayoutInflater = LayoutInflater.from(context) private val colorAnnotation = ContextCompat.getColor(context, R.color.colorAnnotation) private var logs = emptyList() private val timeFormat: DateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM) inner class DebugViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val logTypeView: TextView = itemView.findViewById(R.id.type) val logDateReceivedView: TextView = itemView.findViewById(R.id.dateReceived) val logRawMessage: TextView = itemView.findViewById(R.id.rawMessage) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DebugViewHolder { val itemView = inflater.inflate(R.layout.adapter_debug_layout, parent, false) return DebugViewHolder(itemView) } override fun onBindViewHolder(holder: DebugViewHolder, position: Int) { val current = logs[position] holder.logTypeView.text = current.message_type holder.logRawMessage.text = annotateMessage(current) val date = Date(current.received_date) holder.logDateReceivedView.text = timeFormat.format(date) } /** * Enhance the raw message by visually distinguishing the annotations prior to when * the data was added to the database. * * @see com.geeksville.mesh.ui.DebugFragment.annotateMeshLogs */ private fun annotateMessage(current: MeshLog): CharSequence { val spannable = current.raw_message.toSpannable() REGEX_ANNOTATED_NODE_ID.findAll(spannable).toList().reversed().forEach { spannable.setSpan( android.text.style.StyleSpan(android.graphics.Typeface.ITALIC), it.range.first, it.range.last + 1, SpannedString.SPAN_EXCLUSIVE_EXCLUSIVE ) spannable.setSpan( android.text.style.ForegroundColorSpan(colorAnnotation), it.range.first, it.range.last + 1, SpannedString.SPAN_EXCLUSIVE_EXCLUSIVE ) } return spannable } internal fun setLogs(logs: List) { this.logs = logs notifyDataSetChanged() } override fun getItemCount() = logs.size private companion object { /** * Regex to match the node ID annotations in the MeshLog raw message text. */ val REGEX_ANNOTATED_NODE_ID = Regex("\\(![0-9a-fA-F]{8}\\)$", RegexOption.MULTILINE) } }