Fix width in recovery menu and remove some buttons

This commit is contained in:
kmmiio99o 2025-12-11 18:03:04 +01:00
parent 2b1a7919a3
commit 8bc7c1671d

View file

@ -315,36 +315,40 @@ object LogBoxModule : Module() {
) )
} }
var flavor = "mocha"
// Apply LogBox menu flavor override if present (logbox/LOGBOX_THEMES) // Apply LogBox menu flavor override if present (logbox/LOGBOX_THEMES)
try { try {
val themeFile = File(context.filesDir, "logbox/LOGBOX_THEMES") val themeFile = File(context.filesDir, "logbox/LOGBOX_THEMES")
if (themeFile.exists()) { if (themeFile.exists()) {
val json = JSONObject(themeFile.readText()) val json = JSONObject(themeFile.readText())
val flavor = json.optString("menuFlavor", json.optString("flavor", json.optString("id", ""))).lowercase() val f = json.optString("menuFlavor", json.optString("flavor", json.optString("id", ""))).lowercase()
if (flavor.isNotEmpty()) { if (f.isNotEmpty()) flavor = f
val flavorMap = mapOf( }
"blue" to Pair("#0D47A1", "#82B1FF"),
"green" to Pair("#1B5E20", "#A5D6A7"), if (flavor.isNotEmpty()) {
"mocha" to Pair("#3E2723", "#BCAAA4"), val flavorMap = mapOf(
"vanilla" to Pair("#F9A825", "#FFF59D"), "blue" to Pair("#0D47A1", "#82B1FF"),
"purple" to Pair("#6A1B9A", "#E1BEE7"), "green" to Pair("#1B5E20", "#A5D6A7"),
"amber" to Pair("#FF6F00", "#FFE0B2"), "mocha" to Pair("#3E2723", "#BCAAA4"),
"teal" to Pair("#004D40", "#80CBC4") "vanilla" to Pair("#F9A825", "#FFF59D"),
"purple" to Pair("#6A1B9A", "#E1BEE7"),
"amber" to Pair("#FF6F00", "#FFE0B2"),
"teal" to Pair("#004D40", "#80CBC4")
)
val pair = flavorMap[flavor]
if (pair != null) {
val primary = Color.parseColor(pair.first)
val primaryContainer = Color.parseColor(pair.second)
// Keep contrast choices simple: white on primary for most flavors
val onPrimary = if (isDark) Color.WHITE else Color.WHITE
val onPrimaryContainer = if (isDark) Color.BLACK else Color.BLACK
return base.copy(
primary = primary,
primaryContainer = primaryContainer,
onPrimary = onPrimary,
onPrimaryContainer = onPrimaryContainer
) )
val pair = flavorMap[flavor]
if (pair != null) {
val primary = Color.parseColor(pair.first)
val primaryContainer = Color.parseColor(pair.second)
// Keep contrast choices simple: white on primary for most flavors
val onPrimary = if (isDark) Color.WHITE else Color.WHITE
val onPrimaryContainer = if (isDark) Color.BLACK else Color.BLACK
return base.copy(
primary = primary,
primaryContainer = primaryContainer,
onPrimary = onPrimary,
onPrimaryContainer = onPrimaryContainer
)
}
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -471,11 +475,7 @@ object LogBoxModule : Module() {
handleMenuSelection(context, 2) handleMenuSelection(context, 2)
}) })
// Options Button (opens submenu for theme, injection, flavor)
container.addView(createM3Button(context, "Options", colors) {
dialog.dismiss()
handleMenuSelection(context, 5)
})
// Reload App Button // Reload App Button
container.addView(createM3Button(context, "Reload App", colors) { container.addView(createM3Button(context, "Reload App", colors) {
@ -483,7 +483,17 @@ object LogBoxModule : Module() {
handleMenuSelection(context, 3) handleMenuSelection(context, 3)
}) })
// Options Button (moved last with extra top spacing)
val optionsBtn = createM3Button(context, "Options", colors) {
dialog.dismiss()
handleMenuSelection(context, 5)
}
// increase top margin for visual gap
(optionsBtn.layoutParams as? LinearLayout.LayoutParams)?.let { lp ->
lp.setMargins(lp.leftMargin, dpToPx(context, 16), lp.rightMargin, lp.bottomMargin)
optionsBtn.layoutParams = lp
}
container.addView(optionsBtn)
dialog = AlertDialog.Builder(context) dialog = AlertDialog.Builder(context)
.setView(container) .setView(container)
@ -493,8 +503,11 @@ object LogBoxModule : Module() {
createM3Background(context, Color.TRANSPARENT, 28f) createM3Background(context, Color.TRANSPARENT, 28f)
) )
// Constrain dialog/content width so the menu doesn't span the full screen
constrainContainerWidth(context, container)
currentMenuContainer = container currentMenuContainer = container
dialog.show() dialog.show()
setDialogWindowWidth(dialog, context)
Log.e("Recovery menu shown successfully") Log.e("Recovery menu shown successfully")
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Error showing recovery menu: ${e.message}", e) Log.e("Error showing recovery menu: ${e.message}", e)
@ -607,9 +620,12 @@ object LogBoxModule : Module() {
createM3Background(context, Color.TRANSPARENT, 28f) createM3Background(context, Color.TRANSPARENT, 28f)
) )
// Constrain to sane width before showing
constrainContainerWidth(context, container)
currentMenuContainer = container currentMenuContainer = container
dialog.show() dialog.show()
setDialogWindowWidth(dialog, context)
} }
// Options menu -> entry point for Themes submenu & other options // Options menu -> entry point for Themes submenu & other options
@ -634,6 +650,7 @@ object LogBoxModule : Module() {
setTextColor(colors.onSurface) setTextColor(colors.onSurface)
typeface = android.graphics.Typeface.create("sans-serif", android.graphics.Typeface.BOLD) typeface = android.graphics.Typeface.create("sans-serif", android.graphics.Typeface.BOLD)
setPadding(0, 0, 0, dpToPx(context, 12)) setPadding(0, 0, 0, dpToPx(context, 12))
gravity = Gravity.CENTER
} }
container.addView(titleView) container.addView(titleView)
@ -678,6 +695,8 @@ object LogBoxModule : Module() {
createM3Background(context, Color.TRANSPARENT, 28f) createM3Background(context, Color.TRANSPARENT, 28f)
) )
// Constrain to sane width before showing
constrainContainerWidth(context, container)
currentMenuContainer = container currentMenuContainer = container
dialog.show() dialog.show()
} }
@ -704,6 +723,7 @@ object LogBoxModule : Module() {
setTextColor(colors.onSurface) setTextColor(colors.onSurface)
typeface = android.graphics.Typeface.create("sans-serif", android.graphics.Typeface.BOLD) typeface = android.graphics.Typeface.create("sans-serif", android.graphics.Typeface.BOLD)
setPadding(0, 0, 0, dpToPx(context, 12)) setPadding(0, 0, 0, dpToPx(context, 12))
gravity = Gravity.CENTER
} }
container.addView(titleView) container.addView(titleView)
@ -716,10 +736,6 @@ object LogBoxModule : Module() {
showFlavorSelection(context) showFlavorSelection(context)
}) })
// Back button (return to Options) // Back button (return to Options)
container.addView(createM3Button(context, "Back", colors) { container.addView(createM3Button(context, "Back", colors) {
dialog.dismiss() dialog.dismiss()
@ -736,6 +752,8 @@ object LogBoxModule : Module() {
currentMenuContainer = container currentMenuContainer = container
dialog.show() dialog.show()
setDialogWindowWidth(dialog, context)
setDialogWindowWidth(dialog, context)
} }
// Create a segmented selector (3 options) for appearance mode // Create a segmented selector (3 options) for appearance mode
@ -801,6 +819,9 @@ object LogBoxModule : Module() {
child.background = createM3Background(context, if (sel) colors.primaryContainer else colors.surfaceVariant, 12f) child.background = createM3Background(context, if (sel) colors.primaryContainer else colors.surfaceVariant, 12f)
child.setTextColor(if (sel) colors.onPrimaryContainer else colors.onSurface) child.setTextColor(if (sel) colors.onPrimaryContainer else colors.onSurface)
} }
// Force a repaint of the containing menu so changes are visible immediately
applyMenuColors(context)
} }
} }
row.addView(seg) row.addView(seg)
@ -817,7 +838,6 @@ object LogBoxModule : Module() {
val settings = if (settingsFile.exists()) JSONObject(settingsFile.readText()) else JSONObject() val settings = if (settingsFile.exists()) JSONObject(settingsFile.readText()) else JSONObject()
settings.put("appearanceMode", mode) settings.put("appearanceMode", mode)
settingsFile.writeText(settings.toString()) settingsFile.writeText(settings.toString())
showM3Toast(context, "Appearance set: ${mode.replaceFirstChar { it.uppercase() }}")
applyMenuColors(context) applyMenuColors(context)
} catch (e: Exception) { } catch (e: Exception) {
showError(context, "Failed to set appearance", e.message) showError(context, "Failed to set appearance", e.message)
@ -846,6 +866,7 @@ object LogBoxModule : Module() {
setTextColor(colors.onSurface) setTextColor(colors.onSurface)
typeface = android.graphics.Typeface.create("sans-serif-medium", android.graphics.Typeface.BOLD) typeface = android.graphics.Typeface.create("sans-serif-medium", android.graphics.Typeface.BOLD)
setPadding(0, 0, 0, dpToPx(context, 12)) setPadding(0, 0, 0, dpToPx(context, 12))
gravity = Gravity.CENTER
} }
container.addView(titleView) container.addView(titleView)
@ -867,6 +888,8 @@ object LogBoxModule : Module() {
createM3Background(context, Color.TRANSPARENT, 28f) createM3Background(context, Color.TRANSPARENT, 28f)
) )
// Constrain to sane width before showing
constrainContainerWidth(context, container)
currentMenuContainer = container currentMenuContainer = container
dialog.show() dialog.show()
} }
@ -881,7 +904,6 @@ object LogBoxModule : Module() {
} }
themeFile.writeText(themeJson.toString()) themeFile.writeText(themeJson.toString())
showM3Toast(context, "Menu flavor set to ${flavor.replaceFirstChar { it.uppercase() }}")
applyMenuColors(context) applyMenuColors(context)
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Error saving menu flavor: ${e.message}") Log.e("Error saving menu flavor: ${e.message}")
@ -1220,9 +1242,8 @@ object LogBoxModule : Module() {
Toast.makeText(context, "Please enter a valid URL", Toast.LENGTH_SHORT).show() Toast.makeText(context, "Please enter a valid URL", Toast.LENGTH_SHORT).show()
} }
} catch (e: Exception) { } catch (e: Exception) {
// Build the error message separately to avoid problematic nested/escaped quotes in the string literal val err = e.message ?: "unknown error"
val errMsg = e.message ?: "unknown error" Toast.makeText(context, "Failed to set custom bundle: $err", Toast.LENGTH_LONG).show()
Toast.makeText(context, "Failed to set custom bundle: $errMsg", Toast.LENGTH_LONG).show()
} }
} }
@ -1234,8 +1255,12 @@ object LogBoxModule : Module() {
createM3Background(context, Color.TRANSPARENT, 28f) createM3Background(context, Color.TRANSPARENT, 28f)
) )
// Constrain to sane width before showing
constrainContainerWidth(context, container)
currentMenuContainer = container currentMenuContainer = container
dialog.show() dialog.show()
setDialogWindowWidth(dialog, context)
setDialogWindowWidth(dialog, context)
} }
private fun createM3Switch(context: Context, colors: M3Colors, isChecked: Boolean): View { private fun createM3Switch(context: Context, colors: M3Colors, isChecked: Boolean): View {
@ -1422,34 +1447,97 @@ object LogBoxModule : Module() {
* Apply computed LogBox colors to any currently open menu dialogs in-place. * Apply computed LogBox colors to any currently open menu dialogs in-place.
* This updates backgrounds and the simple button label color so changing the theme * This updates backgrounds and the simple button label color so changing the theme
* or flavor takes effect immediately without restarting Discord or closing the menu. * or flavor takes effect immediately without restarting Discord or closing the menu.
*
* Force a layout/invalidate pass so views repaint with new colors.
*/ */
private fun constrainContainerWidth(context: Context, container: LinearLayout) {
// Limit dialog content width so Xposed dev menu doesn't become extremely wide.
try {
val maxW = (context.resources.displayMetrics.widthPixels * 0.9).toInt()
val lp = LinearLayout.LayoutParams(maxW, ViewGroup.LayoutParams.WRAP_CONTENT)
container.layoutParams = lp
} catch (_: Exception) {
}
}
/**
* After showing the dialog, also constrain the window width to a sane maximum
* (min(90% of screen width, 420dp)) so dialogs don't expand too wide on tablets.
*/
private fun setDialogWindowWidth(dialog: AlertDialog, context: Context) {
try {
val metrics = context.resources.displayMetrics
val maxW = (metrics.widthPixels * 0.9).toInt()
val dp420 = dpToPx(context, 420)
val targetW = if (maxW < dp420) maxW else dp420
dialog.window?.setLayout(targetW, ViewGroup.LayoutParams.WRAP_CONTENT)
} catch (_: Exception) {
}
}
private fun applyMenuColors(context: Context) { private fun applyMenuColors(context: Context) {
try { try {
val container = currentMenuContainer ?: return val container = currentMenuContainer ?: return
val colors = getM3Colors(context) val colors = getM3Colors(context)
// update container background // update container background and all nested children recursively
container.background = createM3Background(context, colors.surface, 28f) fun applyToGroup(group: ViewGroup) {
try {
// update title/subtitle/labels and buttons inside container group.background = createM3Background(context, colors.surface, 28f)
for (i in 0 until container.childCount) { } catch (_: Exception) {}
val child = container.getChildAt(i) for (i in 0 until group.childCount) {
if (child is TextView) { val child = group.getChildAt(i)
// titles and labels use onSurface/onSurfaceVariant where appropriate try {
child.setTextColor(colors.onSurface) when (child) {
} else if (child is LinearLayout) { is EditText -> {
// update button rows and nested views // EditText is a TextView subclass - ensure both text and hint colors update
for (j in 0 until child.childCount) { child.setTextColor(colors.onSurface)
val inner = child.getChildAt(j) child.setHintTextColor(colors.onSurfaceVariant)
if (inner is TextView) { try {
// update label colors to remain readable child.background = createM3Background(context, colors.surfaceVariant, 12f)
inner.setTextColor(colors.onSurface) } catch (_: Exception) {}
} else if (inner is ViewGroup) { }
applyMenuColorsToGroup(inner, colors, context) is TextView -> {
child.setTextColor(colors.onSurface)
}
is ViewGroup -> {
// If it's a clickable button-like group, style it as a button
if (child.isClickable && child.childCount > 0 && child.getChildAt(0) is TextView) {
try {
child.background = createM3Background(context, colors.primaryContainer, 20f)
(child.getChildAt(0) as TextView).setTextColor(colors.onPrimaryContainer)
} catch (_: Exception) {}
}
applyToGroup(child)
}
else -> {
// nothing special
}
} }
} catch (_: Exception) {
} }
// Force redraw on the child
try {
child.invalidate()
child.requestLayout()
} catch (_: Exception) {}
} }
} }
applyToGroup(container)
// also ensure container invalidates/repaints on main thread and nudge visibility to force redraw
try {
container.post {
container.invalidate()
container.requestLayout()
val prev = container.visibility
container.visibility = View.GONE
container.visibility = prev
}
} catch (_: Exception) {}
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Error applying menu colors: ${e.message}") Log.e("Error applying menu colors: ${e.message}")
} }
@ -1535,8 +1623,10 @@ object LogBoxModule : Module() {
) )
// Expose this container so applyMenuColors can update error dialog visuals immediately // Expose this container so applyMenuColors can update error dialog visuals immediately
constrainContainerWidth(context, container)
currentMenuContainer = container currentMenuContainer = container
dialog.show() dialog.show()
setDialogWindowWidth(dialog, context)
} }
} }