diff --git a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt index 4065bb8a4..54301ce8f 100644 --- a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt +++ b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt @@ -20,12 +20,18 @@ import com.chuckerteam.chucker.internal.support.highlightWithDefinedColors * We're using a [RecyclerView] to show the content of the body line by line to do not affect * performances when loading big payloads. */ -internal class TransactionBodyAdapter( - private val bodyItems: List -) : RecyclerView.Adapter() { +internal class TransactionBodyAdapter : RecyclerView.Adapter() { + + private val items = arrayListOf() + + fun setItems(bodyItems: List) { + items.clear() + items.addAll(bodyItems) + notifyDataSetChanged() + } override fun onBindViewHolder(holder: TransactionPayloadViewHolder, position: Int) { - holder.bind(bodyItems[position]) + holder.bind(items[position]) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionPayloadViewHolder { @@ -46,10 +52,10 @@ internal class TransactionBodyAdapter( } } - override fun getItemCount() = bodyItems.size + override fun getItemCount() = items.size override fun getItemViewType(position: Int): Int { - return when (bodyItems[position]) { + return when (items[position]) { is TransactionPayloadItem.HeaderItem -> TYPE_HEADERS is TransactionPayloadItem.BodyLineItem -> TYPE_BODY_LINE is TransactionPayloadItem.ImageItem -> TYPE_IMAGE @@ -57,7 +63,7 @@ internal class TransactionBodyAdapter( } internal fun highlightQueryWithColors(newText: String, backgroundColor: Int, foregroundColor: Int) { - bodyItems.filterIsInstance() + items.filterIsInstance() .withIndex() .forEach { (index, item) -> if (item.line.contains(newText, ignoreCase = true)) { @@ -77,7 +83,7 @@ internal class TransactionBodyAdapter( } internal fun resetHighlight() { - bodyItems.filterIsInstance() + items.filterIsInstance() .withIndex() .forEach { (index, item) -> val spans = item.line.getSpans(0, item.line.length - 1, Any::class.java) diff --git a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt index 877b1e76b..4e8c745ed 100644 --- a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt +++ b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt @@ -41,6 +41,7 @@ internal class TransactionPayloadFragment : Fragment(), SearchView.OnQueryTextListener { private lateinit var payloadBinding: ChuckerFragmentTransactionPayloadBinding + private val payloadAdapter = TransactionBodyAdapter() private var backgroundSpanColor: Int = Color.YELLOW private var foregroundSpanColor: Int = Color.RED @@ -72,21 +73,54 @@ internal class TransactionPayloadFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + payloadBinding.payloadRecyclerView.apply { + setHasFixedSize(true) + adapter = payloadAdapter + } + viewModel.transaction.observe( viewLifecycleOwner, Observer { transaction -> if (transaction == null) return@Observer uiScope.launch { - showProgress() + payloadBinding.loadingProgress.visibility = View.VISIBLE + val result = processPayload(type, transaction) - payloadBinding.responseRecyclerView.adapter = TransactionBodyAdapter(result) - payloadBinding.responseRecyclerView.setHasFixedSize(true) - hideProgress() + if (result.isEmpty()) { + showEmptyState() + } else { + payloadAdapter.setItems(result) + showPayloadState() + } + // Invalidating menu, because we need to hide menu items for empty payloads + requireActivity().invalidateOptionsMenu() + + payloadBinding.loadingProgress.visibility = View.GONE } } ) } + private fun showEmptyState() { + payloadBinding.apply { + emptyPayloadTextView.text = if (type == TYPE_RESPONSE) { + getString(R.string.chucker_response_is_empty) + } else { + getString(R.string.chucker_request_is_empty) + } + emptyStateGroup.visibility = View.VISIBLE + payloadRecyclerView.visibility = View.GONE + } + } + + private fun showPayloadState() { + payloadBinding.apply { + emptyStateGroup.visibility = View.GONE + payloadRecyclerView.visibility = View.VISIBLE + } + } + override fun onDestroy() { super.onDestroy() uiScope.cancel() @@ -184,30 +218,14 @@ internal class TransactionPayloadFragment : override fun onQueryTextSubmit(query: String): Boolean = false override fun onQueryTextChange(newText: String): Boolean { - val adapter = (payloadBinding.responseRecyclerView.adapter as TransactionBodyAdapter) if (newText.isNotBlank() && newText.length > NUMBER_OF_IGNORED_SYMBOLS) { - adapter.highlightQueryWithColors(newText, backgroundSpanColor, foregroundSpanColor) + payloadAdapter.highlightQueryWithColors(newText, backgroundSpanColor, foregroundSpanColor) } else { - adapter.resetHighlight() + payloadAdapter.resetHighlight() } return true } - private fun showProgress() { - payloadBinding.apply { - loadingProgress.visibility = View.VISIBLE - responseRecyclerView.visibility = View.INVISIBLE - } - } - - private fun hideProgress() { - payloadBinding.apply { - loadingProgress.visibility = View.INVISIBLE - responseRecyclerView.visibility = View.VISIBLE - requireActivity().invalidateOptionsMenu() - } - } - private suspend fun processPayload( type: Int, transaction: HttpTransaction @@ -249,8 +267,10 @@ internal class TransactionPayloadFragment : result.add(TransactionPayloadItem.BodyLineItem(SpannableStringBuilder.valueOf(it))) } } else { - bodyString.lines().forEach { - result.add(TransactionPayloadItem.BodyLineItem(SpannableStringBuilder.valueOf(it))) + if (bodyString.isNotBlank()) { + bodyString.lines().forEach { + result.add(TransactionPayloadItem.BodyLineItem(SpannableStringBuilder.valueOf(it))) + } } } return@withContext result diff --git a/library/src/main/res/drawable/chucker_empty_payload.xml b/library/src/main/res/drawable/chucker_empty_payload.xml new file mode 100644 index 000000000..fd78e00f4 --- /dev/null +++ b/library/src/main/res/drawable/chucker_empty_payload.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/library/src/main/res/layout/chucker_fragment_transaction_payload.xml b/library/src/main/res/layout/chucker_fragment_transaction_payload.xml index d0b055209..12628b931 100755 --- a/library/src/main/res/layout/chucker_fragment_transaction_payload.xml +++ b/library/src/main/res/layout/chucker_fragment_transaction_payload.xml @@ -1,5 +1,5 @@ - - + android:indeterminate="true" + android:visibility="visible" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + + + + tools:visibility="visible" /> + + - + diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml index 5a3f35da4..fe066b6be 100644 --- a/library/src/main/res/values/strings.xml +++ b/library/src/main/res/values/strings.xml @@ -52,4 +52,6 @@ Setup binary data The request isn\'t ready for sharing or saving + This request is empty + This response is empty