diff --git a/app/src/main/java/se/ajpanton/notificationlog/ViewLogsFragment.kt b/app/src/main/java/se/ajpanton/notificationlog/ViewLogsFragment.kt index ce06810..be3739c 100644 --- a/app/src/main/java/se/ajpanton/notificationlog/ViewLogsFragment.kt +++ b/app/src/main/java/se/ajpanton/notificationlog/ViewLogsFragment.kt @@ -107,7 +107,11 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) { val metadata = metadataValues(row.entry, settings) val contents = fieldValue(LogField.CONTENTS, row.entry, settings) val hasContents = LogField.CONTENTS in settings.visibleFields && !contents.isNullOrEmpty() - val metadataPill = metadataPill(metadata).apply { + val toggleExpanded = { + if (!expandedIds.add(row.entry.id)) expandedIds.remove(row.entry.id) + renderExpanded(row.entry.id in expandedIds) + } + val metadataPill = metadataPill(metadata, expanded, toggleExpanded, row.entry.id).apply { layoutParams = LinearLayout.LayoutParams( if (hasContents) 0 else LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, @@ -118,10 +122,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) { } if (metadata.isNotEmpty()) addView(metadataPill) if (hasContents) { - val contentsPill = contentsPill(row, contents!!, metadata.size.coerceAtLeast(1), expanded) { - if (!expandedIds.add(row.entry.id)) expandedIds.remove(row.entry.id) - renderExpanded(row.entry.id in expandedIds) - }.apply { + val contentsPill = contentsPill(row, contents!!, metadata.size.coerceAtLeast(1), expanded, toggleExpanded).apply { layoutParams = LinearLayout.LayoutParams( if (metadata.isNotEmpty()) 0 else LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, @@ -139,21 +140,34 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) { } } - private fun metadataPill(values: List): LinearLayout = LinearLayout(requireContext()).apply { + private fun metadataPill( + values: List, + expanded: Boolean, + onToggleExpanded: () -> Unit, + entryId: String, + ): LinearLayout = LinearLayout(requireContext()).apply { orientation = LinearLayout.VERTICAL background = androidx.core.content.ContextCompat.getDrawable(context, R.drawable.log_pill_background) setPadding(dp(12), dp(8), dp(12), dp(8)) + isClickable = true + isFocusable = true values.forEach { value -> addView(TextView(context).apply { - text = value.text - maxLines = 1 - ellipsize = TextUtils.TruncateAt.END + text = if (expanded && value.breakBeforePeriods) value.text.replace(".", "\u200B.") else value.text + maxLines = if (expanded) Int.MAX_VALUE else 1 + ellipsize = if (expanded) null else TextUtils.TruncateAt.END + if (expanded) { + breakStrategy = android.text.Layout.BREAK_STRATEGY_HIGH_QUALITY + hyphenationFrequency = android.text.Layout.HYPHENATION_FREQUENCY_NONE + } textSize = value.textSize if (value.indented) setPadding(dp(8), 0, 0, 0) setLineSpacing(0f, 1f) if (value.bold) setTypeface(typeface, android.graphics.Typeface.BOLD) }) } + setOnClickListener { onToggleExpanded() } + setOnLongClickListener { showDeleteDialog(entryId) } } private fun contentsPill( @@ -216,7 +230,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) { private fun metadataValues(entry: NotificationLogEntry, settings: LogViewSettings): List = buildList { if (LogField.TIMESTAMP in settings.visibleFields) add(MetadataValue(timestamp(entry.recordedAtEpochMillis, settings.timestampZone, entry.eventTimeZoneId), 12f)) if (LogField.APP_NAME in settings.visibleFields) add(MetadataValue(entry.appName, 15f, indented = true, bold = true)) - if (LogField.PACKAGE_NAME in settings.visibleFields) add(MetadataValue(entry.packageName, 12f, indented = true)) + if (LogField.PACKAGE_NAME in settings.visibleFields) add(MetadataValue(entry.packageName, 12f, indented = true, breakBeforePeriods = true)) if (LogField.ACTION in settings.visibleFields) add(MetadataValue(actionLabel(entry.action), 14f, indented = true)) } @@ -282,7 +296,13 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) { private fun dp(value: Int): Int = (value * resources.displayMetrics.density).toInt() private data class LogRow(val entry: NotificationLogEntry) - private data class MetadataValue(val text: String, val textSize: Float, val indented: Boolean = false, val bold: Boolean = false) + private data class MetadataValue( + val text: String, + val textSize: Float, + val indented: Boolean = false, + val bold: Boolean = false, + val breakBeforePeriods: Boolean = false, + ) private companion object { const val LEFT_PILL_WEIGHT = 0.42f