manager: add module background banners"

module devs can add banners for their modules through module.prop config

Example:

banner=https://something.com/banner.png
This commit is contained in:
rifsxd
2025-06-03 00:29:02 +06:00
parent 3f7e731df6
commit f91afe6c46
4 changed files with 538 additions and 468 deletions

View File

@@ -96,7 +96,7 @@ fun CustomizationScreen(navigator: DestinationsNavigator) {
) )
} }
SwitchItem( SwitchItem(
icon = Icons.Filled.ColorLens, icon = Icons.Filled.Dashboard,
title = stringResource(id = R.string.settings_legacyui), title = stringResource(id = R.string.settings_legacyui),
summary = stringResource(id = R.string.settings_legacyui_summary), summary = stringResource(id = R.string.settings_legacyui_summary),
checked = useLagacyUI checked = useLagacyUI
@@ -105,6 +105,22 @@ fun CustomizationScreen(navigator: DestinationsNavigator) {
useLagacyUI = it useLagacyUI = it
} }
var useBanner by rememberSaveable {
mutableStateOf(
prefs.getBoolean("use_banner", true)
)
}
SwitchItem(
enabled = !useLagacyUI,
icon = Icons.Filled.ViewCarousel,
title = stringResource(id = R.string.settings_banner),
summary = stringResource(id = R.string.settings_banner_summary),
checked = useBanner
) {
prefs.edit().putBoolean("use_banner", it).apply()
useBanner = it
}
var enableAmoled by rememberSaveable { var enableAmoled by rememberSaveable {
mutableStateOf( mutableStateOf(
prefs.getBoolean("enable_amoled", false) prefs.getBoolean("enable_amoled", false)

View File

@@ -1,5 +1,6 @@
package com.rifsxd.ksunext.ui.screen package com.rifsxd.ksunext.ui.screen
import android.app.Activity.RESULT_OK import android.app.Activity.RESULT_OK
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -8,6 +9,8 @@ import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -21,6 +24,7 @@ import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.only
@@ -68,6 +72,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -93,6 +100,7 @@ import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import coil.compose.AsyncImage
import com.rifsxd.ksunext.Natives import com.rifsxd.ksunext.Natives
import com.rifsxd.ksunext.R import com.rifsxd.ksunext.R
import com.rifsxd.ksunext.ksuApp import com.rifsxd.ksunext.ksuApp
@@ -677,22 +685,61 @@ fun ModuleItem(
ElevatedCard( ElevatedCard(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Box(
modifier = Modifier
.fillMaxWidth()
) {
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val useLagacyUI = prefs.getBoolean("use_legacyui", false)
val useBanner = prefs.getBoolean("use_banner", true)
if (useBanner && !useLagacyUI && module.banner.isNotEmpty()) {
Box(
modifier = Modifier
.matchParentSize(),
contentAlignment = Alignment.Center
) {
AsyncImage(
model = module.banner,
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
contentScale = ContentScale.Crop,
alpha = 0.18f
)
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.background(
Brush.verticalGradient(
colors = listOf(
Color.Black.copy(alpha = 0.0f),
Color.Black.copy(alpha = 0.9f)
),
startY = 0f,
endY = Float.POSITIVE_INFINITY
)
)
)
}
}
Column {
val textDecoration = if (!module.remove) null else TextDecoration.LineThrough val textDecoration = if (!module.remove) null else TextDecoration.LineThrough
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
val indication = LocalIndication.current val indication = LocalIndication.current
val viewModel = viewModel<ModuleViewModel>() val viewModel = viewModel<ModuleViewModel>()
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
var developerOptionsEnabled by rememberSaveable { var developerOptionsEnabled by rememberSaveable {
mutableStateOf( mutableStateOf(
prefs.getBoolean("enable_developer_options", false) prefs.getBoolean("enable_developer_options", false)
) )
} }
val useLagacyUI = prefs.getBoolean("use_legacyui", false)
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
developerOptionsEnabled = prefs.getBoolean("enable_developer_options", false) developerOptionsEnabled = prefs.getBoolean("enable_developer_options", false)
} }
@@ -1182,6 +1229,8 @@ fun ModuleItem(
} }
} }
} }
}
}
fun formatSize(size: Long): String { fun formatSize(size: Long): String {
val kb = 1024 val kb = 1024
@@ -1212,7 +1261,8 @@ fun ModuleItemPreview() {
hasWebUi = false, hasWebUi = false,
hasActionScript = false, hasActionScript = false,
dirId = "dirId", dirId = "dirId",
size = 12345678L size = 12345678L,
banner = ""
) )
ModuleItem(EmptyDestinationsNavigator, module, "", {}, {}, {}, {}, {}) ModuleItem(EmptyDestinationsNavigator, module, "", {}, {}, {}, {}, {})
} }

View File

@@ -46,7 +46,8 @@ class ModuleViewModel : ViewModel() {
val hasWebUi: Boolean, val hasWebUi: Boolean,
val hasActionScript: Boolean, val hasActionScript: Boolean,
val dirId: String, val dirId: String,
val size: Long val size: Long,
val banner: String
) )
data class ModuleUpdateInfo( data class ModuleUpdateInfo(
@@ -142,7 +143,8 @@ class ModuleViewModel : ViewModel() {
obj.optBoolean("web"), obj.optBoolean("web"),
obj.optBoolean("action"), obj.optBoolean("action"),
dirId, dirId,
size size,
obj.optString("banner")
) )
}.toList() }.toList()
isNeedRefresh = false isNeedRefresh = false

View File

@@ -213,6 +213,8 @@
<string name="settings_language">Language</string> <string name="settings_language">Language</string>
<string name="settings_legacyui">Use Legacy UI</string> <string name="settings_legacyui">Use Legacy UI</string>
<string name="settings_legacyui_summary">Switch to the previous user interface style.</string> <string name="settings_legacyui_summary">Switch to the previous user interface style.</string>
<string name="settings_banner">Enable banners</string>
<string name="settings_banner_summary">Show background banners for modules.</string>
<string name="use_webuix">Use WebUI X</string> <string name="use_webuix">Use WebUI X</string>
<string name="use_webuix_summary">Use WebUI X instead of WebUI, which supports more APIs.</string> <string name="use_webuix_summary">Use WebUI X instead of WebUI, which supports more APIs.</string>
<string name="use_webuix_eruda">Inject Eruda into WebUI X</string> <string name="use_webuix_eruda">Inject Eruda into WebUI X</string>