Fix width in recovery menu and remove some buttons
This commit is contained in:
parent
2b1a7919a3
commit
8bc7c1671d
1 changed files with 147 additions and 57 deletions
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue