Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 113 additions & 5 deletions app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,22 @@ import android.app.Activity
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewTreeObserver
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Button
import android.widget.RelativeLayout
import androidx.activity.viewModels
import androidx.annotation.GravityInt
import androidx.core.graphics.Insets
import androidx.core.view.AccessibilityDelegateCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
Expand Down Expand Up @@ -188,6 +193,7 @@ class EditorBottomSheet

mediator.attach()
binding.pager.isUserInputEnabled = false
setupBuildStatusAccessibility()

binding.tabs.addOnTabSelectedListener(
object : OnTabSelectedListener {
Expand Down Expand Up @@ -254,10 +260,6 @@ class EditorBottomSheet
copyDiagnosticsToClipboard()
}

binding.headerContainer.setOnClickListener {
viewModel.setSheetState(sheetState = BottomSheetBehavior.STATE_EXPANDED)
}

ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->
this.windowInsets =
insets.getInsets(WindowInsetsCompat.Type.mandatorySystemGestures())
Expand All @@ -280,7 +282,7 @@ class EditorBottomSheet
binding.clearFab.setOnClickListener(null)
binding.clearFab.setOnLongClickListener(null)
binding.copyDiagnosticsFab.setOnClickListener(null)
binding.headerContainer.setOnClickListener(null)
ViewCompat.setAccessibilityDelegate(binding.buildStatus.buildStatusLayout, null)
removeOnLayoutChangeListener(fabLayoutChangeListener)
ViewCompat.setOnApplyWindowInsetsListener(this, null)

Expand Down Expand Up @@ -315,6 +317,110 @@ class EditorBottomSheet
}
}

private fun setupBuildStatusAccessibility() {
val buildStatus = binding.buildStatus.buildStatusLayout
buildStatus.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES
binding.buildStatus.statusText.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
binding.buildStatus.swipeHint.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
updateBuildStatusContentDescription()

ViewCompat.setAccessibilityDelegate(
buildStatus,
object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(
host: View,
info: AccessibilityNodeInfoCompat,
) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.className = Button::class.java.name
info.isClickable = true
val expanded = isOutputPanelExpanded()
info.addAction(
AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfo.ACTION_CLICK,
getOutputPanelActionLabel(expanded),
),
)

if (expanded) {
info.addAction(
AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfo.ACTION_COLLAPSE,
context.getString(string.action_collapse_output_panel),
),
)
} else {
info.addAction(
AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfo.ACTION_EXPAND,
context.getString(string.action_expand_output_panel),
),
)
}
}

override fun performAccessibilityAction(
host: View,
action: Int,
args: Bundle?,
): Boolean =
when (action) {
AccessibilityNodeInfo.ACTION_CLICK ->
if (isOutputPanelExpanded()) {
collapseOutputPanel()
} else {
expandOutputPanel()
}

AccessibilityNodeInfo.ACTION_EXPAND -> expandOutputPanel()

AccessibilityNodeInfo.ACTION_COLLAPSE -> collapseOutputPanel()
else -> super.performAccessibilityAction(host, action, args)
}
},
)
}

private fun expandOutputPanel(): Boolean {
if (viewModel.sheetBehaviorState != BottomSheetBehavior.STATE_EXPANDED) {
viewModel.setSheetState(sheetState = BottomSheetBehavior.STATE_EXPANDED)
}
updateBuildStatusContentDescription()
return true
}

private fun collapseOutputPanel(): Boolean {
if (viewModel.sheetBehaviorState != BottomSheetBehavior.STATE_COLLAPSED) {
viewModel.setSheetState(sheetState = BottomSheetBehavior.STATE_COLLAPSED)
}
updateBuildStatusContentDescription()
return true
}

private fun isOutputPanelExpanded(): Boolean =
viewModel.sheetBehaviorState == BottomSheetBehavior.STATE_EXPANDED ||
viewModel.sheetBehaviorState == BottomSheetBehavior.STATE_HALF_EXPANDED

private fun getOutputPanelActionLabel(expanded: Boolean = isOutputPanelExpanded()): String =
context.getString(
if (expanded) {
string.action_collapse_output_panel
} else {
string.action_expand_output_panel
},
)

private fun updateBuildStatusContentDescription() {
val statusText = binding.buildStatus.statusText.text?.toString()?.trim().orEmpty()
val actionLabel = getOutputPanelActionLabel()
binding.buildStatus.buildStatusLayout.contentDescription =
if (statusText.isEmpty()) {
context.getString(string.cd_build_status_output_panel_empty, actionLabel)
} else {
context.getString(string.cd_build_status_output_panel, statusText, actionLabel)
}
}

private fun generateTooltipListener(tooltipTag: String): OnLongClickListener =
OnLongClickListener { view: View ->
TooltipManager.showIdeCategoryTooltip(
Expand Down Expand Up @@ -526,6 +632,7 @@ class EditorBottomSheet
binding.buildStatus.let {
it.statusText.gravity = gravity
it.statusText.text = text
updateBuildStatusContentDescription()
}
}
}
Expand Down Expand Up @@ -599,6 +706,7 @@ class EditorBottomSheet
BottomSheetBehavior.STATE_DRAGGING, BottomSheetBehavior.STATE_SETTLING -> return
}

updateBuildStatusContentDescription()
updateFabTranslation()
val currentFragment = pagerAdapter.getFragmentAtIndex<Fragment>(state.currentTab)

Expand Down
4 changes: 4 additions & 0 deletions resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@
<string name="xml_validation_error_generic">We could not open this layout. Fix the XML and try again.</string>
<string name="title_generating_xml">Generating XML code</string>
<string name="msg_swipe_up">Swipe up to display logs, diagnostics, debug info, and more</string>
<string name="cd_build_status_output_panel_empty">Build status. %1$s.</string>
<string name="cd_build_status_output_panel">Build status: %1$s. %2$s.</string>
<string name="action_expand_output_panel">Open output panel</string>
<string name="action_collapse_output_panel">Close output panel</string>
<string name="preview_render_error_title">Preview Unavailable</string>
<string name="preview_render_error_message">Could not create a root view. The XML is empty or missing a valid top-level element.</string>

Expand Down
Loading