diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/webui/MonetColorsProvider.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/webui/MonetColorsProvider.kt new file mode 100644 index 00000000..c67d193e --- /dev/null +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/webui/MonetColorsProvider.kt @@ -0,0 +1,55 @@ +package com.rifsxd.ksunext.ui.webui + +import android.content.Context +import android.content.res.Configuration +import android.os.Build + +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.ui.graphics.toArgb + +/** + * @author rifsxd + * @date 2025/6/2. + */ +object MonetColorsProvider { + fun getColorsCss(context: Context): String { + + // Detect dark mode + val isDark = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES + + val colorScheme = if (isDark) { + dynamicDarkColorScheme(context) + } else { + dynamicLightColorScheme(context) + } + + val monetColors = mapOf( + "primary" to colorScheme.primary.toArgb().toHex(), + "onPrimary" to colorScheme.onPrimary.toArgb().toHex(), + "background" to colorScheme.background.toArgb().toHex(), + "onSurface" to colorScheme.onSurface.toArgb().toHex(), + "onSurfaceVariant" to colorScheme.onSurfaceVariant.toArgb().toHex(), + "tonalSurface" to colorScheme.surface.toArgb().toHex(), + "surfaceBright" to colorScheme.surfaceVariant.toArgb().toHex(), + "outlineVariant" to colorScheme.outlineVariant.toArgb().toHex(), + "error" to colorScheme.error.toArgb().toHex() + ) + + return monetColors.toCssVars() + } + + private fun Map.toCssVars(): String { + return buildString { + append(":root {\n") + for ((k, v) in this@toCssVars) { + append(" --$k: $v;\n") + } + append("}\n") + } + } + + private fun Int.toHex(): String { + return String.format("#%06X", 0xFFFFFF and this) + } +} \ No newline at end of file diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/webui/SuFilePathHandler.java b/manager/app/src/main/java/com/rifsxd/ksunext/ui/webui/SuFilePathHandler.java index 22fd75be..3db807f2 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/webui/SuFilePathHandler.java +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/webui/SuFilePathHandler.java @@ -1,6 +1,7 @@ package com.rifsxd.ksunext.ui.webui; import android.content.Context; +import android.os.Build; import android.util.Log; import android.webkit.WebResourceResponse; @@ -15,8 +16,12 @@ import com.topjohnwu.superuser.io.SuFileInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; import java.util.zip.GZIPInputStream; +import com.rifsxd.ksunext.ui.webui.MonetColorsProvider; + /** * Handler class to open files from file system by root access * For more information about android storage please refer to @@ -81,8 +86,11 @@ public final class SuFilePathHandler implements WebViewAssetLoader.PathHandler { * which files can be loaded. * @throws IllegalArgumentException if the directory is not allowed. */ + private final Context mContext; + public SuFilePathHandler(@NonNull Context context, @NonNull File directory, Shell rootShell) { try { + mContext = context; mDirectory = new File(getCanonicalDirPath(directory)); if (!isAllowedInternalStorageDir(context)) { throw new IllegalArgumentException("The given directory \"" + directory @@ -130,6 +138,16 @@ public final class SuFilePathHandler implements WebViewAssetLoader.PathHandler { @WorkerThread @NonNull public WebResourceResponse handle(@NonNull String path) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if ("internal/colors.css".equals(path)) { + String css = MonetColorsProvider.INSTANCE.getColorsCss(mContext); + return new WebResourceResponse( + "text/css", + "utf-8", + new ByteArrayInputStream(css.getBytes(StandardCharsets.UTF_8)) + ); + } + } try { File file = getCanonicalFileIfChild(mDirectory, path); if (file != null) {