react-native-security-suite 0.6.7 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/android/build.gradle +0 -15
  2. package/android/src/main/AndroidManifest.xml +3 -48
  3. package/package.json +1 -1
  4. package/android/src/main/java/com/securitysuite/NetworkLogger.java +0 -25
  5. package/android/src/main/java/com/securitysuite/api/BodyDecoder.kt +0 -35
  6. package/android/src/main/java/com/securitysuite/api/Chucker.kt +0 -108
  7. package/android/src/main/java/com/securitysuite/api/ChuckerCollector.kt +0 -129
  8. package/android/src/main/java/com/securitysuite/api/ChuckerInterceptor.kt +0 -280
  9. package/android/src/main/java/com/securitysuite/api/ExportFormat.kt +0 -12
  10. package/android/src/main/java/com/securitysuite/api/RetentionManager.kt +0 -109
  11. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpHeader.kt +0 -8
  12. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransaction.kt +0 -344
  13. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransactionTuple.kt +0 -62
  14. package/android/src/main/java/com/securitysuite/internal/data/har/Har.kt +0 -13
  15. package/android/src/main/java/com/securitysuite/internal/data/har/Log.kt +0 -24
  16. package/android/src/main/java/com/securitysuite/internal/data/har/log/Browser.kt +0 -11
  17. package/android/src/main/java/com/securitysuite/internal/data/har/log/Creator.kt +0 -11
  18. package/android/src/main/java/com/securitysuite/internal/data/har/log/Entry.kt +0 -49
  19. package/android/src/main/java/com/securitysuite/internal/data/har/log/Page.kt +0 -14
  20. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Cache.kt +0 -12
  21. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Header.kt +0 -17
  22. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Request.kt +0 -35
  23. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Response.kt +0 -33
  24. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Timings.kt +0 -25
  25. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/cache/SecondaryRequest.kt +0 -13
  26. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/PostData.kt +0 -20
  27. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/QueryString.kt +0 -23
  28. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/postdata/Params.kt +0 -13
  29. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/response/Content.kt +0 -30
  30. package/android/src/main/java/com/securitysuite/internal/data/har/log/page/PageTimings.kt +0 -11
  31. package/android/src/main/java/com/securitysuite/internal/data/model/DialogData.kt +0 -8
  32. package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionDatabaseRepository.kt +0 -60
  33. package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionRepository.kt +0 -33
  34. package/android/src/main/java/com/securitysuite/internal/data/repository/RepositoryProvider.kt +0 -38
  35. package/android/src/main/java/com/securitysuite/internal/data/room/ChuckerDatabase.kt +0 -22
  36. package/android/src/main/java/com/securitysuite/internal/data/room/HttpTransactionDao.kt +0 -53
  37. package/android/src/main/java/com/securitysuite/internal/support/BitmapUtils.kt +0 -45
  38. package/android/src/main/java/com/securitysuite/internal/support/CacheDirectoryProvider.kt +0 -11
  39. package/android/src/main/java/com/securitysuite/internal/support/ChessboardDrawable.kt +0 -76
  40. package/android/src/main/java/com/securitysuite/internal/support/ChuckerFileProvider.kt +0 -9
  41. package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseJobIntentServiceReceiver.kt +0 -14
  42. package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseService.kt +0 -32
  43. package/android/src/main/java/com/securitysuite/internal/support/ContextExt.kt +0 -22
  44. package/android/src/main/java/com/securitysuite/internal/support/DepletingSource.kt +0 -37
  45. package/android/src/main/java/com/securitysuite/internal/support/FileFactory.kt +0 -30
  46. package/android/src/main/java/com/securitysuite/internal/support/FileSaver.kt +0 -41
  47. package/android/src/main/java/com/securitysuite/internal/support/FormatUtils.kt +0 -117
  48. package/android/src/main/java/com/securitysuite/internal/support/FormattedUrl.kt +0 -76
  49. package/android/src/main/java/com/securitysuite/internal/support/HarUtils.kt +0 -28
  50. package/android/src/main/java/com/securitysuite/internal/support/HttpUrlUtils.kt +0 -11
  51. package/android/src/main/java/com/securitysuite/internal/support/JsonConverter.kt +0 -19
  52. package/android/src/main/java/com/securitysuite/internal/support/LimitingSource.kt +0 -22
  53. package/android/src/main/java/com/securitysuite/internal/support/LiveDataUtils.kt +0 -68
  54. package/android/src/main/java/com/securitysuite/internal/support/Logger.kt +0 -43
  55. package/android/src/main/java/com/securitysuite/internal/support/NotificationHelper.kt +0 -149
  56. package/android/src/main/java/com/securitysuite/internal/support/OkHttpUtils.kt +0 -86
  57. package/android/src/main/java/com/securitysuite/internal/support/OkioUtils.kt +0 -34
  58. package/android/src/main/java/com/securitysuite/internal/support/PlainTextDecoder.kt +0 -30
  59. package/android/src/main/java/com/securitysuite/internal/support/ReportingSink.kt +0 -114
  60. package/android/src/main/java/com/securitysuite/internal/support/RequestProcessor.kt +0 -102
  61. package/android/src/main/java/com/securitysuite/internal/support/ResponseProcessor.kt +0 -170
  62. package/android/src/main/java/com/securitysuite/internal/support/SearchHighlightUtil.kt +0 -80
  63. package/android/src/main/java/com/securitysuite/internal/support/Sharable.kt +0 -86
  64. package/android/src/main/java/com/securitysuite/internal/support/SpanTextUtil.kt +0 -202
  65. package/android/src/main/java/com/securitysuite/internal/support/TeeSource.kt +0 -68
  66. package/android/src/main/java/com/securitysuite/internal/support/TransactionCurlCommandSharable.kt +0 -46
  67. package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsHarSharable.kt +0 -11
  68. package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsSharable.kt +0 -73
  69. package/android/src/main/java/com/securitysuite/internal/support/TransactionDiffCallback.kt +0 -26
  70. package/android/src/main/java/com/securitysuite/internal/support/TransactionListDetailsSharable.kt +0 -23
  71. package/android/src/main/java/com/securitysuite/internal/ui/BaseChuckerActivity.kt +0 -35
  72. package/android/src/main/java/com/securitysuite/internal/ui/MainActivity.kt +0 -375
  73. package/android/src/main/java/com/securitysuite/internal/ui/MainViewModel.kt +0 -47
  74. package/android/src/main/java/com/securitysuite/internal/ui/transaction/PayloadType.kt +0 -6
  75. package/android/src/main/java/com/securitysuite/internal/ui/transaction/ProtocolResources.kt +0 -14
  76. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionActivity.kt +0 -186
  77. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionAdapter.kt +0 -139
  78. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionOverviewFragment.kt +0 -100
  79. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPagerAdapter.kt +0 -29
  80. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadAdapter.kt +0 -269
  81. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadFragment.kt +0 -529
  82. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionViewModel.kt +0 -69
  83. package/android/src/main/res/A.java +0 -12
  84. package/android/src/main/res/color/chucker_fab_background_colour.xml +0 -5
  85. package/android/src/main/res/drawable/chucker_empty_payload.xml +0 -10
  86. package/android/src/main/res/drawable/chucker_ic_arrow_down.xml +0 -10
  87. package/android/src/main/res/drawable/chucker_ic_copy.xml +0 -12
  88. package/android/src/main/res/drawable/chucker_ic_decoded_url_white.xml +0 -10
  89. package/android/src/main/res/drawable/chucker_ic_delete_white.xml +0 -9
  90. package/android/src/main/res/drawable/chucker_ic_encoded_url_white.xml +0 -11
  91. package/android/src/main/res/drawable/chucker_ic_graphql.xml +0 -27
  92. package/android/src/main/res/drawable/chucker_ic_http.xml +0 -10
  93. package/android/src/main/res/drawable/chucker_ic_https.xml +0 -9
  94. package/android/src/main/res/drawable/chucker_ic_launcher_foreground.xml +0 -14
  95. package/android/src/main/res/drawable/chucker_ic_save_white.xml +0 -9
  96. package/android/src/main/res/drawable/chucker_ic_search_white.xml +0 -9
  97. package/android/src/main/res/drawable/chucker_ic_share_white.xml +0 -9
  98. package/android/src/main/res/drawable/chucker_ic_transaction_notification.xml +0 -9
  99. package/android/src/main/res/layout/activity_main.xml +0 -83
  100. package/android/src/main/res/layout/activity_transaction.xml +0 -48
  101. package/android/src/main/res/layout/fragment_transaction_overview.xml +0 -365
  102. package/android/src/main/res/layout/fragment_transaction_payload.xml +0 -132
  103. package/android/src/main/res/layout/list_item_transaction.xml +0 -122
  104. package/android/src/main/res/layout/transaction_item_body_line.xml +0 -13
  105. package/android/src/main/res/layout/transaction_item_copy.xml +0 -19
  106. package/android/src/main/res/layout/transaction_item_headers.xml +0 -12
  107. package/android/src/main/res/layout/transaction_item_image.xml +0 -16
  108. package/android/src/main/res/menu/chucker_transaction.xml +0 -46
  109. package/android/src/main/res/menu/chucker_transactions_list.xml +0 -41
  110. package/android/src/main/res/mipmap-anydpi-v26/chucker_ic_launcher.xml +0 -5
  111. package/android/src/main/res/mipmap-hdpi/chucker_ic_launcher.png +0 -0
  112. package/android/src/main/res/mipmap-xhdpi/chucker_ic_launcher.png +0 -0
  113. package/android/src/main/res/mipmap-xxhdpi/chucker_ic_launcher.png +0 -0
  114. package/android/src/main/res/mipmap-xxxhdpi/chucker_ic_launcher.png +0 -0
  115. package/android/src/main/res/values/chucker_ic_launcher_background.xml +0 -4
  116. package/android/src/main/res/values/colors.xml +0 -38
  117. package/android/src/main/res/values/dimens.xml +0 -10
  118. package/android/src/main/res/values/public.xml +0 -5
  119. package/android/src/main/res/values/strings.xml +0 -77
  120. package/android/src/main/res/values/styles.xml +0 -44
  121. package/android/src/main/res/values-es/strings.xml +0 -75
  122. package/android/src/main/res/values-night/colors.xml +0 -32
  123. package/android/src/main/res/xml/chucker_provider_paths.xml +0 -4
@@ -1,139 +0,0 @@
1
- package com.securitysuite.internal.ui.transaction
2
-
3
- import android.annotation.SuppressLint
4
- import android.content.Context
5
- import android.content.res.ColorStateList
6
- import android.view.LayoutInflater
7
- import android.view.ViewGroup
8
- import androidx.appcompat.content.res.AppCompatResources
9
- import androidx.core.content.ContextCompat
10
- import androidx.core.view.isVisible
11
- import androidx.core.widget.ImageViewCompat
12
- import androidx.recyclerview.widget.ListAdapter
13
- import androidx.recyclerview.widget.RecyclerView
14
- import com.securitysuite.R
15
- import com.securitysuite.databinding.ListItemTransactionBinding
16
- import com.securitysuite.internal.data.entity.HttpTransaction
17
- import com.securitysuite.internal.data.entity.HttpTransactionTuple
18
- import com.securitysuite.internal.support.TransactionDiffCallback
19
- import java.text.DateFormat
20
- import javax.net.ssl.HttpsURLConnection
21
-
22
- internal class TransactionAdapter internal constructor(
23
- context: Context,
24
- private val onTransactionClick: (Long) -> Unit,
25
- ) : ListAdapter<HttpTransactionTuple, TransactionAdapter.TransactionViewHolder>(
26
- TransactionDiffCallback,
27
- ) {
28
- private val colorDefault: Int = ContextCompat.getColor(context, R.color.chucker_status_default)
29
- private val colorRequested: Int =
30
- ContextCompat.getColor(
31
- context,
32
- R.color.chucker_status_requested,
33
- )
34
- private val colorError: Int = ContextCompat.getColor(context, R.color.chucker_status_error)
35
- private val color500: Int = ContextCompat.getColor(context, R.color.chucker_status_500)
36
- private val color400: Int = ContextCompat.getColor(context, R.color.chucker_status_400)
37
- private val color300: Int = ContextCompat.getColor(context, R.color.chucker_status_300)
38
-
39
- override fun onCreateViewHolder(
40
- parent: ViewGroup,
41
- viewType: Int,
42
- ): TransactionViewHolder {
43
- val viewBinding =
44
- ListItemTransactionBinding.inflate(
45
- LayoutInflater.from(parent.context),
46
- parent,
47
- false,
48
- )
49
- return TransactionViewHolder(viewBinding)
50
- }
51
-
52
- override fun onBindViewHolder(
53
- holder: TransactionViewHolder,
54
- position: Int,
55
- ) = holder.bind(getItem(position))
56
-
57
- inner class TransactionViewHolder(
58
- private val itemBinding: ListItemTransactionBinding,
59
- ) : RecyclerView.ViewHolder(itemBinding.root) {
60
- private var transactionId: Long? = null
61
-
62
- init {
63
- itemView.setOnClickListener {
64
- transactionId?.let {
65
- onTransactionClick.invoke(it)
66
- }
67
- }
68
- }
69
-
70
- @SuppressLint("SetTextI18n")
71
- fun bind(transaction: HttpTransactionTuple) {
72
- transactionId = transaction.id
73
-
74
- itemBinding.apply {
75
- displayGraphQlFields(transaction.graphQlOperationName, transaction.graphQlDetected)
76
- path.text = "${transaction.method} ${transaction.getFormattedPath(encode = false)}"
77
- host.text = transaction.host
78
- timeStart.text = DateFormat.getTimeInstance().format(transaction.requestDate)
79
-
80
- setProtocolImage(if (transaction.isSsl) ProtocolResources.Https() else ProtocolResources.Http())
81
-
82
- if (transaction.status === HttpTransaction.Status.Complete) {
83
- code.text = transaction.responseCode.toString()
84
- duration.text = transaction.durationString
85
- size.text = transaction.totalSizeString
86
- } else {
87
- code.text = ""
88
- duration.text = ""
89
- size.text = ""
90
- }
91
- if (transaction.status === HttpTransaction.Status.Failed) {
92
- code.text = "!!!"
93
- }
94
- }
95
-
96
- setStatusColor(transaction)
97
- }
98
-
99
- private fun setProtocolImage(resources: ProtocolResources) {
100
- itemBinding.ssl.setImageDrawable(
101
- AppCompatResources.getDrawable(
102
- itemView.context,
103
- resources.icon,
104
- ),
105
- )
106
- ImageViewCompat.setImageTintList(
107
- itemBinding.ssl,
108
- ColorStateList.valueOf(ContextCompat.getColor(itemView.context, resources.color)),
109
- )
110
- }
111
-
112
- private fun setStatusColor(transaction: HttpTransactionTuple) {
113
- val color: Int =
114
- when {
115
- (transaction.status === HttpTransaction.Status.Failed) -> colorError
116
- (transaction.status === HttpTransaction.Status.Requested) -> colorRequested
117
- (transaction.responseCode == null) -> colorDefault
118
- (transaction.responseCode!! >= HttpsURLConnection.HTTP_INTERNAL_ERROR) -> color500
119
- (transaction.responseCode!! >= HttpsURLConnection.HTTP_BAD_REQUEST) -> color400
120
- (transaction.responseCode!! >= HttpsURLConnection.HTTP_MULT_CHOICE) -> color300
121
- else -> colorDefault
122
- }
123
- itemBinding.code.setTextColor(color)
124
- itemBinding.path.setTextColor(color)
125
- }
126
- }
127
- }
128
-
129
- private fun ListItemTransactionBinding.displayGraphQlFields(
130
- graphQlOperationName: String?,
131
- graphQLDetected: Boolean,
132
- ) {
133
- graphqlIcon.isVisible = graphQLDetected
134
- graphqlPath.isVisible = graphQLDetected
135
-
136
- if (graphQLDetected) {
137
- graphqlPath.text = graphQlOperationName ?: root.resources.getString(R.string.chucker_graphql_operation_is_empty)
138
- }
139
- }
@@ -1,100 +0,0 @@
1
- package com.securitysuite.internal.ui.transaction
2
-
3
- import android.os.Bundle
4
- import android.view.LayoutInflater
5
- import android.view.Menu
6
- import android.view.MenuInflater
7
- import android.view.View
8
- import android.view.ViewGroup
9
- import androidx.fragment.app.Fragment
10
- import androidx.fragment.app.activityViewModels
11
- import androidx.lifecycle.Observer
12
- import com.securitysuite.R
13
- import com.securitysuite.databinding.FragmentTransactionOverviewBinding
14
- import com.securitysuite.internal.data.entity.HttpTransaction
15
- import com.securitysuite.internal.support.combineLatest
16
-
17
- internal class TransactionOverviewFragment : Fragment() {
18
- private val viewModel: TransactionViewModel by activityViewModels { TransactionViewModelFactory() }
19
-
20
- private lateinit var overviewBinding: FragmentTransactionOverviewBinding
21
-
22
- override fun onCreate(savedInstanceState: Bundle?) {
23
- super.onCreate(savedInstanceState)
24
- setHasOptionsMenu(true)
25
- }
26
-
27
- override fun onCreateView(
28
- inflater: LayoutInflater,
29
- container: ViewGroup?,
30
- savedInstanceState: Bundle?,
31
- ): View? {
32
- overviewBinding = FragmentTransactionOverviewBinding.inflate(inflater, container, false)
33
- return overviewBinding.root
34
- }
35
-
36
- override fun onCreateOptionsMenu(
37
- menu: Menu,
38
- inflater: MenuInflater,
39
- ) {
40
- menu.findItem(R.id.save_body).isVisible = false
41
- viewModel.doesUrlRequireEncoding.observe(
42
- viewLifecycleOwner,
43
- Observer { menu.findItem(R.id.encode_url).isVisible = it },
44
- )
45
-
46
- super.onCreateOptionsMenu(menu, inflater)
47
- }
48
-
49
- override fun onViewCreated(
50
- view: View,
51
- savedInstanceState: Bundle?,
52
- ) {
53
- super.onViewCreated(view, savedInstanceState)
54
-
55
- viewModel.transaction.combineLatest(viewModel.encodeUrl).observe(
56
- viewLifecycleOwner,
57
- Observer { (transaction, encodeUrl) -> populateUI(transaction, encodeUrl) },
58
- )
59
- }
60
-
61
- private fun populateUI(
62
- transaction: HttpTransaction?,
63
- encodeUrl: Boolean,
64
- ) {
65
- with(overviewBinding) {
66
- url.text = transaction?.getFormattedUrl(encodeUrl)
67
- method.text = transaction?.method
68
- protocol.text = transaction?.protocol
69
- status.text = transaction?.status.toString()
70
- response.text = transaction?.responseSummaryText
71
- when (transaction?.isSsl) {
72
- null -> {
73
- sslGroup.visibility = View.GONE
74
- }
75
- true -> {
76
- sslGroup.visibility = View.VISIBLE
77
- sslValue.setText(R.string.chucker_yes)
78
- }
79
- else -> {
80
- sslGroup.visibility = View.VISIBLE
81
- sslValue.setText(R.string.chucker_no)
82
- }
83
- }
84
- if (transaction?.responseTlsVersion != null) {
85
- tlsVersionValue.text = transaction.responseTlsVersion
86
- tlsGroup.visibility = View.VISIBLE
87
- }
88
- if (transaction?.responseCipherSuite != null) {
89
- cipherSuiteValue.text = transaction.responseCipherSuite
90
- cipherSuiteGroup.visibility = View.VISIBLE
91
- }
92
- requestTime.text = transaction?.requestDateString
93
- responseTime.text = transaction?.responseDateString
94
- duration.text = transaction?.durationString
95
- requestSize.text = transaction?.requestSizeString
96
- responseSize.text = transaction?.responseSizeString
97
- totalSize.text = transaction?.totalSizeString
98
- }
99
- }
100
- }
@@ -1,29 +0,0 @@
1
- package com.securitysuite.internal.ui.transaction
2
-
3
- import android.content.Context
4
- import androidx.fragment.app.Fragment
5
- import androidx.fragment.app.FragmentManager
6
- import androidx.fragment.app.FragmentStatePagerAdapter
7
- import com.securitysuite.R
8
-
9
- internal class TransactionPagerAdapter(context: Context, fm: FragmentManager) :
10
- FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
11
- private val titles =
12
- arrayOf(
13
- context.getString(R.string.chucker_overview),
14
- context.getString(R.string.chucker_request),
15
- context.getString(R.string.chucker_response),
16
- )
17
-
18
- override fun getItem(position: Int): Fragment =
19
- when (position) {
20
- 0 -> TransactionOverviewFragment()
21
- 1 -> TransactionPayloadFragment.newInstance(PayloadType.REQUEST)
22
- 2 -> TransactionPayloadFragment.newInstance(PayloadType.RESPONSE)
23
- else -> throw IllegalArgumentException("no item")
24
- }
25
-
26
- override fun getCount(): Int = titles.size
27
-
28
- override fun getPageTitle(position: Int): CharSequence = titles[position]
29
- }
@@ -1,269 +0,0 @@
1
- package com.securitysuite.internal.ui.transaction
2
-
3
- import android.graphics.Bitmap
4
- import android.graphics.drawable.Drawable
5
- import android.text.SpannableStringBuilder
6
- import android.text.Spanned
7
- import android.view.LayoutInflater
8
- import android.view.View
9
- import android.view.ViewGroup
10
- import androidx.core.text.getSpans
11
- import androidx.recyclerview.widget.RecyclerView
12
- import com.securitysuite.R
13
- import com.securitysuite.databinding.TransactionItemBodyLineBinding
14
- import com.securitysuite.databinding.TransactionItemCopyBinding
15
- import com.securitysuite.databinding.TransactionItemHeadersBinding
16
- import com.securitysuite.databinding.TransactionItemImageBinding
17
- import com.securitysuite.internal.support.ChessboardDrawable
18
- import com.securitysuite.internal.support.SpanTextUtil
19
- import com.securitysuite.internal.support.highlightWithDefinedColors
20
- import com.securitysuite.internal.support.highlightWithDefinedColorsSubstring
21
- import com.securitysuite.internal.support.indicesOf
22
-
23
- /**
24
- * Adapter responsible of showing the content of the Transaction Request/Response body.
25
- * We're using a [RecyclerView] to show the content of the body line by line to do not affect
26
- * performances when loading big payloads.
27
- */
28
- internal class TransactionBodyAdapter(private val onCopyBodyListener: () -> Unit) :
29
- RecyclerView.Adapter<TransactionPayloadViewHolder>() {
30
- private val items = arrayListOf<TransactionPayloadItem>()
31
-
32
- fun setItems(bodyItems: List<TransactionPayloadItem>) {
33
- val previousItemCount = items.size
34
- items.clear()
35
- items.addAll(bodyItems)
36
- notifyItemRangeRemoved(0, previousItemCount)
37
- notifyItemRangeInserted(0, items.size)
38
- }
39
-
40
- override fun onBindViewHolder(
41
- holder: TransactionPayloadViewHolder,
42
- position: Int,
43
- ) {
44
- holder.bind(items[position])
45
- }
46
-
47
- override fun onCreateViewHolder(
48
- parent: ViewGroup,
49
- viewType: Int,
50
- ): TransactionPayloadViewHolder {
51
- val inflater = LayoutInflater.from(parent.context)
52
- return when (viewType) {
53
- TYPE_HEADERS -> {
54
- val headersItemBinding = TransactionItemHeadersBinding.inflate(inflater, parent, false)
55
- TransactionPayloadViewHolder.HeaderViewHolder(headersItemBinding)
56
- }
57
-
58
- TYPE_BODY_LINE -> {
59
- val bodyItemBinding = TransactionItemBodyLineBinding.inflate(inflater, parent, false)
60
- TransactionPayloadViewHolder.BodyLineViewHolder(bodyItemBinding)
61
- }
62
-
63
- TYPE_COPY -> {
64
- val copyItemBinding =
65
- TransactionItemCopyBinding.inflate(inflater, parent, false)
66
- TransactionPayloadViewHolder.CopyViewHolder(copyItemBinding, onCopyBodyListener)
67
- }
68
-
69
- else -> {
70
- val imageItemBinding = TransactionItemImageBinding.inflate(inflater, parent, false)
71
- TransactionPayloadViewHolder.ImageViewHolder(imageItemBinding)
72
- }
73
- }
74
- }
75
-
76
- override fun getItemCount() = items.size
77
-
78
- override fun getItemViewType(position: Int): Int {
79
- return when (items[position]) {
80
- is TransactionPayloadItem.HeaderItem -> TYPE_HEADERS
81
- is TransactionPayloadItem.BodyLineItem -> TYPE_BODY_LINE
82
- is TransactionPayloadItem.ImageItem -> TYPE_IMAGE
83
- is TransactionPayloadItem.CopyItem -> TYPE_COPY
84
- }
85
- }
86
-
87
- internal fun highlightQueryWithColors(
88
- newText: String,
89
- backgroundColor: Int,
90
- foregroundColor: Int,
91
- ): List<SearchItemBodyLine> {
92
- val listOfSearchItems = arrayListOf<SearchItemBodyLine>()
93
- items.filterIsInstance<TransactionPayloadItem.BodyLineItem>()
94
- .withIndex()
95
- .forEach { (index, item) ->
96
- val listOfOccurrences = item.line.indicesOf(newText)
97
- if (listOfOccurrences.isNotEmpty()) {
98
- // storing the occurrences and their positions
99
- listOfOccurrences.forEach {
100
- listOfSearchItems.add(
101
- SearchItemBodyLine(
102
- indexBodyLine = index + 1,
103
- indexStartOfQuerySubString = it,
104
- ),
105
- )
106
- }
107
-
108
- // highlighting the occurrences
109
- item.line.clearHighlightSpans()
110
- item.line =
111
- item.line.highlightWithDefinedColors(
112
- newText,
113
- listOfOccurrences,
114
- backgroundColor,
115
- foregroundColor,
116
- )
117
- notifyItemChanged(index + 1)
118
- } else {
119
- // Let's clear the spans if we haven't found the query string.
120
- val removedSpansCount = item.line.clearHighlightSpans()
121
- if (removedSpansCount > 0) {
122
- notifyItemChanged(index + 1)
123
- }
124
- }
125
- }
126
- return listOfSearchItems
127
- }
128
-
129
- internal fun highlightItemWithColorOnPosition(
130
- position: Int,
131
- queryStartPosition: Int,
132
- queryText: String,
133
- backgroundColor: Int,
134
- foregroundColor: Int,
135
- ) {
136
- val item = items.getOrNull(position) as? TransactionPayloadItem.BodyLineItem
137
- if (item != null) {
138
- item.line =
139
- item.line.highlightWithDefinedColorsSubstring(
140
- queryText,
141
- queryStartPosition,
142
- backgroundColor,
143
- foregroundColor,
144
- )
145
- notifyItemChanged(position)
146
- }
147
- }
148
-
149
- internal fun resetHighlight() {
150
- items.filterIsInstance<TransactionPayloadItem.BodyLineItem>()
151
- .withIndex()
152
- .forEach { (index, item) ->
153
- val removedSpansCount = item.line.clearHighlightSpans()
154
- if (removedSpansCount > 0) {
155
- notifyItemChanged(index + 1)
156
- }
157
- }
158
- }
159
-
160
- companion object {
161
- private const val TYPE_HEADERS = 1
162
- private const val TYPE_BODY_LINE = 2
163
- private const val TYPE_IMAGE = 3
164
- private const val TYPE_COPY = 4
165
- }
166
-
167
- /**
168
- * Clear span that created during search process
169
- * @return Number of spans that removed.
170
- */
171
- private fun SpannableStringBuilder.clearHighlightSpans(): Int {
172
- var removedSpansCount = 0
173
- val spanList = getSpans<Any>(0, length)
174
- for (span in spanList)
175
- if (span !is SpanTextUtil.ChuckerForegroundColorSpan) {
176
- removeSpan(span)
177
- removedSpansCount++
178
- }
179
- return removedSpansCount
180
- }
181
-
182
- internal data class SearchItemBodyLine(
183
- val indexBodyLine: Int,
184
- val indexStartOfQuerySubString: Int,
185
- )
186
- }
187
-
188
- internal sealed class TransactionPayloadViewHolder(view: View) : RecyclerView.ViewHolder(view) {
189
- abstract fun bind(item: TransactionPayloadItem)
190
-
191
- internal class HeaderViewHolder(
192
- private val headerBinding: TransactionItemHeadersBinding,
193
- ) : TransactionPayloadViewHolder(headerBinding.root) {
194
- override fun bind(item: TransactionPayloadItem) {
195
- if (item is TransactionPayloadItem.HeaderItem) {
196
- headerBinding.responseHeaders.text = item.headers
197
- }
198
- }
199
- }
200
-
201
- internal class CopyViewHolder(
202
- private val copyBinding: TransactionItemCopyBinding,
203
- private val onCopyBodyListener: () -> Unit,
204
- ) : TransactionPayloadViewHolder(copyBinding.root) {
205
- override fun bind(item: TransactionPayloadItem) {
206
- if (item is TransactionPayloadItem.CopyItem) {
207
- copyBinding.responseCopy.visibility = View.VISIBLE
208
- copyBinding.responseCopy.setOnClickListener {
209
- onCopyBodyListener.invoke()
210
- }
211
- }
212
- }
213
- }
214
-
215
- internal class BodyLineViewHolder(
216
- private val bodyBinding: TransactionItemBodyLineBinding,
217
- ) : TransactionPayloadViewHolder(bodyBinding.root) {
218
- override fun bind(item: TransactionPayloadItem) {
219
- if (item is TransactionPayloadItem.BodyLineItem) {
220
- bodyBinding.bodyLine.text = item.line
221
- }
222
- }
223
- }
224
-
225
- internal class ImageViewHolder(
226
- private val imageBinding: TransactionItemImageBinding,
227
- ) : TransactionPayloadViewHolder(imageBinding.root) {
228
- override fun bind(item: TransactionPayloadItem) {
229
- if (item is TransactionPayloadItem.ImageItem) {
230
- imageBinding.binaryData.setImageBitmap(item.image)
231
- imageBinding.root.background = createContrastingBackground(item.luminance)
232
- }
233
- }
234
-
235
- private fun createContrastingBackground(luminance: Double?): Drawable? {
236
- if (luminance == null) return null
237
-
238
- return if (luminance < LUMINANCE_THRESHOLD) {
239
- ChessboardDrawable.createPattern(
240
- itemView.context,
241
- R.color.chucker_chessboard_even_square_light,
242
- R.color.chucker_chessboard_odd_square_light,
243
- R.dimen.chucker_half_grid,
244
- )
245
- } else {
246
- ChessboardDrawable.createPattern(
247
- itemView.context,
248
- R.color.chucker_chessboard_even_square_dark,
249
- R.color.chucker_chessboard_odd_square_dark,
250
- R.dimen.chucker_half_grid,
251
- )
252
- }
253
- }
254
-
255
- private companion object {
256
- const val LUMINANCE_THRESHOLD = 0.25
257
- }
258
- }
259
- }
260
-
261
- internal sealed class TransactionPayloadItem {
262
- internal class HeaderItem(val headers: Spanned) : TransactionPayloadItem()
263
-
264
- internal class CopyItem(val copy: String) : TransactionPayloadItem()
265
-
266
- internal class BodyLineItem(var line: SpannableStringBuilder) : TransactionPayloadItem()
267
-
268
- internal class ImageItem(val image: Bitmap, val luminance: Double?) : TransactionPayloadItem()
269
- }