feat: replace FeatherIcons with Iconsax in PluginCard and PluginPermissionsDialog for improved UI consistency

This commit is contained in:
Kingkor Roy Tirtho 2026-07-16 22:29:29 +06:00
parent 0b3d21f255
commit 70cabedc9e
6 changed files with 322 additions and 23 deletions

View File

@ -38,17 +38,17 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import compose.icons.FeatherIcons
import compose.icons.feathericons.Check
import compose.icons.feathericons.Package
import compose.icons.feathericons.Tag
import compose.icons.feathericons.Trash2
import compose.icons.feathericons.User
import dev.krtirtho.spotube.core.ui.base.GhostIconButton
import dev.krtirtho.spotube.core.ui.base.OutlineButton
import dev.krtirtho.spotube.modules.plugin.BUILT_IN_PLUGINS
import dev.krtirtho.spotube.modules.plugin.PluginAbility
import dev.krtirtho.spotube.modules.plugin.PluginEntry
import dev.krtirtho.spotube.resources.iconsax.Iconsax
import dev.krtirtho.spotube.resources.iconsax.IconsaxBox
import dev.krtirtho.spotube.resources.iconsax.IconsaxCheckSquare
import dev.krtirtho.spotube.resources.iconsax.IconsaxTag
import dev.krtirtho.spotube.resources.iconsax.IconsaxTrash
import dev.krtirtho.spotube.resources.iconsax.User
import org.jetbrains.compose.resources.stringResource
import spotube.composeapp.generated.resources.Res
import spotube.composeapp.generated.resources.plugin_action_remove
@ -87,7 +87,7 @@ internal fun PluginCard(
) {
Box(contentAlignment = Alignment.Center) {
Icon(
FeatherIcons.Package,
Iconsax.IconsaxBox,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(22.dp)
@ -124,7 +124,7 @@ internal fun PluginCard(
horizontalArrangement = Arrangement.spacedBy(3.dp)
) {
Icon(
FeatherIcons.Check,
Iconsax.IconsaxCheckSquare,
contentDescription = null,
modifier = Modifier.size(10.dp),
tint = MaterialTheme.colorScheme.primary
@ -159,7 +159,7 @@ internal fun PluginCard(
horizontalArrangement = Arrangement.spacedBy(3.dp)
) {
Icon(
FeatherIcons.User,
Iconsax.User,
contentDescription = null,
modifier = Modifier.size(11.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant
@ -176,7 +176,7 @@ internal fun PluginCard(
horizontalArrangement = Arrangement.spacedBy(3.dp)
) {
Icon(
FeatherIcons.Tag,
Iconsax.IconsaxTag,
contentDescription = null,
modifier = Modifier.size(11.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant
@ -233,10 +233,9 @@ internal fun PluginCard(
} else {
GhostIconButton(onClick = onRemove) {
Icon(
FeatherIcons.Trash2,
Iconsax.IconsaxTrash,
contentDescription = stringResource(Res.string.plugin_action_remove),
tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(18.dp)
)
}
}

View File

@ -47,14 +47,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import compose.icons.FeatherIcons
import compose.icons.feathericons.Database
import compose.icons.feathericons.Eye
import compose.icons.feathericons.Package
import compose.icons.feathericons.User
import compose.icons.feathericons.Wifi
import dev.krtirtho.spotube.modules.plugin.PluginCapability
import dev.krtirtho.spotube.modules.plugin.PluginEntry
import dev.krtirtho.spotube.resources.iconsax.Iconsax
import dev.krtirtho.spotube.resources.iconsax.IconsaxBoxAdd
import dev.krtirtho.spotube.resources.iconsax.IconsaxEye
import dev.krtirtho.spotube.resources.iconsax.IconsaxWifiSquare
import dev.krtirtho.spotube.resources.iconsax.PhosphorDatabaseDuotone
import dev.krtirtho.spotube.resources.iconsax.User
import org.jetbrains.compose.resources.stringResource
import spotube.composeapp.generated.resources.Res
import spotube.composeapp.generated.resources.plugin_permissions_api_diff
@ -118,7 +118,7 @@ fun PluginPermissionDialog(
) {
Box(contentAlignment = Alignment.Center) {
Icon(
imageVector = FeatherIcons.Package,
imageVector = Iconsax.IconsaxBoxAdd,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(24.dp)
@ -146,7 +146,7 @@ fun PluginPermissionDialog(
horizontalArrangement = Arrangement.spacedBy(6.dp)
) {
Icon(
FeatherIcons.User,
Iconsax.User,
contentDescription = null,
modifier = Modifier.size(13.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant
@ -328,17 +328,17 @@ private fun VersionStat(label: String, value: String) {
private fun CapabilityRow(capability: PluginCapability) {
val (icon, label, description) = when (capability) {
PluginCapability.PERSISTENT_STORAGE -> Triple(
FeatherIcons.Database,
Iconsax.PhosphorDatabaseDuotone,
stringResource(Res.string.plugin_permissions_capability_storage_title),
stringResource(Res.string.plugin_permissions_capability_storage_desc)
)
PluginCapability.NETWORK_REQUESTS -> Triple(
FeatherIcons.Wifi,
Iconsax.IconsaxWifiSquare,
stringResource(Res.string.plugin_permissions_capability_network_title),
stringResource(Res.string.plugin_permissions_capability_network_desc)
)
PluginCapability.WEBVIEW -> Triple(
FeatherIcons.Eye,
Iconsax.IconsaxEye,
stringResource(Res.string.plugin_permissions_capability_webview_title),
stringResource(Res.string.plugin_permissions_capability_webview_desc)
)

View File

@ -0,0 +1,69 @@
package dev.krtirtho.spotube.resources.iconsax
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.PathData
import androidx.compose.ui.graphics.vector.group
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
val Iconsax.IconsaxEye: ImageVector
get() {
if (_IconsaxEye != null) {
return _IconsaxEye!!
}
_IconsaxEye = ImageVector.Builder(
name = "IconsaxEye",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
).apply {
group(
clipPathData = PathData {
moveTo(0f, 0f)
horizontalLineToRelative(24f)
verticalLineToRelative(24f)
horizontalLineToRelative(-24f)
close()
}
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 0.4f,
strokeAlpha = 0.4f
) {
moveTo(21.25f, 9.15f)
curveTo(18.94f, 5.52f, 15.56f, 3.43f, 12f, 3.43f)
curveTo(10.22f, 3.43f, 8.49f, 3.95f, 6.91f, 4.92f)
curveTo(5.33f, 5.9f, 3.91f, 7.33f, 2.75f, 9.15f)
curveTo(1.75f, 10.72f, 1.75f, 13.27f, 2.75f, 14.84f)
curveTo(5.06f, 18.48f, 8.44f, 20.56f, 12f, 20.56f)
curveTo(13.78f, 20.56f, 15.51f, 20.04f, 17.09f, 19.07f)
curveTo(18.67f, 18.09f, 20.09f, 16.66f, 21.25f, 14.84f)
curveTo(22.25f, 13.28f, 22.25f, 10.72f, 21.25f, 9.15f)
close()
moveTo(12f, 16.04f)
curveTo(9.76f, 16.04f, 7.96f, 14.23f, 7.96f, 12f)
curveTo(7.96f, 9.77f, 9.76f, 7.96f, 12f, 7.96f)
curveTo(14.24f, 7.96f, 16.04f, 9.77f, 16.04f, 12f)
curveTo(16.04f, 14.23f, 14.24f, 16.04f, 12f, 16.04f)
close()
}
path(fill = SolidColor(Color.White)) {
moveTo(12f, 9.141f)
curveTo(10.43f, 9.141f, 9.15f, 10.421f, 9.15f, 12.001f)
curveTo(9.15f, 13.571f, 10.43f, 14.851f, 12f, 14.851f)
curveTo(13.57f, 14.851f, 14.86f, 13.571f, 14.86f, 12.001f)
curveTo(14.86f, 10.431f, 13.57f, 9.141f, 12f, 9.141f)
close()
}
}
}.build()
return _IconsaxEye!!
}
@Suppress("ObjectPropertyName")
private var _IconsaxEye: ImageVector? = null

View File

@ -0,0 +1,65 @@
package dev.krtirtho.spotube.resources.iconsax
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.PathData
import androidx.compose.ui.graphics.vector.group
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
val Iconsax.IconsaxTag: ImageVector
get() {
if (_IconsaxTag != null) {
return _IconsaxTag!!
}
_IconsaxTag = ImageVector.Builder(
name = "IconsaxTag",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
).apply {
group(
clipPathData = PathData {
moveTo(0f, 0f)
horizontalLineToRelative(24f)
verticalLineToRelative(24f)
horizontalLineToRelative(-24f)
close()
}
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 0.4f,
strokeAlpha = 0.4f
) {
moveTo(4.17f, 15.3f)
lineTo(8.7f, 19.83f)
curveTo(10.56f, 21.69f, 13.58f, 21.69f, 15.45f, 19.83f)
lineTo(19.84f, 15.44f)
curveTo(21.7f, 13.58f, 21.7f, 10.56f, 19.84f, 8.69f)
lineTo(15.3f, 4.17f)
curveTo(14.35f, 3.22f, 13.04f, 2.71f, 11.7f, 2.78f)
lineTo(6.7f, 3.02f)
curveTo(4.7f, 3.11f, 3.11f, 4.7f, 3.01f, 6.69f)
lineTo(2.77f, 11.69f)
curveTo(2.71f, 13.04f, 3.22f, 14.35f, 4.17f, 15.3f)
close()
}
path(fill = SolidColor(Color.White)) {
moveTo(9.5f, 12.38f)
curveTo(11.091f, 12.38f, 12.38f, 11.091f, 12.38f, 9.5f)
curveTo(12.38f, 7.91f, 11.091f, 6.62f, 9.5f, 6.62f)
curveTo(7.91f, 6.62f, 6.62f, 7.91f, 6.62f, 9.5f)
curveTo(6.62f, 11.091f, 7.91f, 12.38f, 9.5f, 12.38f)
close()
}
}
}.build()
return _IconsaxTag!!
}
@Suppress("ObjectPropertyName")
private var _IconsaxTag: ImageVector? = null

View File

@ -0,0 +1,88 @@
package dev.krtirtho.spotube.resources.iconsax
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.PathData
import androidx.compose.ui.graphics.vector.group
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
val Iconsax.IconsaxWifiSquare: ImageVector
get() {
if (_IconsaxWifiSquare != null) {
return _IconsaxWifiSquare!!
}
_IconsaxWifiSquare = ImageVector.Builder(
name = "IconsaxWifiSquare",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
).apply {
group(
clipPathData = PathData {
moveTo(0f, 0f)
horizontalLineToRelative(24f)
verticalLineToRelative(24f)
horizontalLineToRelative(-24f)
close()
}
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 0.4f,
strokeAlpha = 0.4f
) {
moveTo(16.19f, 2f)
horizontalLineTo(7.82f)
curveTo(4.17f, 2f, 2f, 4.17f, 2f, 7.81f)
verticalLineTo(16.18f)
curveTo(2f, 19.82f, 4.17f, 21.99f, 7.81f, 21.99f)
horizontalLineTo(16.18f)
curveTo(19.82f, 21.99f, 21.99f, 19.82f, 21.99f, 16.18f)
verticalLineTo(7.81f)
curveTo(22f, 4.17f, 19.83f, 2f, 16.19f, 2f)
close()
}
path(fill = SolidColor(Color.White)) {
moveTo(18f, 10.71f)
curveTo(17.84f, 10.71f, 17.68f, 10.66f, 17.54f, 10.55f)
curveTo(14.17f, 7.95f, 9.82f, 7.95f, 6.46f, 10.55f)
curveTo(6.13f, 10.8f, 5.66f, 10.74f, 5.41f, 10.42f)
curveTo(5.16f, 10.09f, 5.22f, 9.62f, 5.54f, 9.37f)
curveTo(9.46f, 6.34f, 14.53f, 6.34f, 18.46f, 9.37f)
curveTo(18.79f, 9.62f, 18.85f, 10.09f, 18.59f, 10.42f)
curveTo(18.45f, 10.61f, 18.22f, 10.71f, 18f, 10.71f)
close()
}
path(fill = SolidColor(Color.White)) {
moveTo(16.4f, 13.8f)
curveTo(16.24f, 13.8f, 16.08f, 13.75f, 15.94f, 13.64f)
curveTo(13.54f, 11.79f, 10.45f, 11.79f, 8.05f, 13.64f)
curveTo(7.72f, 13.89f, 7.25f, 13.83f, 7f, 13.51f)
curveTo(6.75f, 13.19f, 6.81f, 12.71f, 7.13f, 12.46f)
curveTo(10.08f, 10.18f, 13.9f, 10.18f, 16.85f, 12.46f)
curveTo(17.18f, 12.71f, 17.24f, 13.18f, 16.98f, 13.51f)
curveTo(16.85f, 13.7f, 16.63f, 13.8f, 16.4f, 13.8f)
close()
}
path(fill = SolidColor(Color.White)) {
moveTo(14.2f, 16.889f)
curveTo(14.04f, 16.889f, 13.88f, 16.84f, 13.74f, 16.729f)
curveTo(12.68f, 15.91f, 11.31f, 15.91f, 10.25f, 16.729f)
curveTo(9.92f, 16.979f, 9.45f, 16.92f, 9.2f, 16.6f)
curveTo(8.95f, 16.27f, 9.01f, 15.8f, 9.33f, 15.55f)
curveTo(10.92f, 14.319f, 13.06f, 14.319f, 14.65f, 15.55f)
curveTo(14.98f, 15.8f, 15.04f, 16.27f, 14.78f, 16.6f)
curveTo(14.65f, 16.789f, 14.43f, 16.889f, 14.2f, 16.889f)
close()
}
}
}.build()
return _IconsaxWifiSquare!!
}
@Suppress("ObjectPropertyName")
private var _IconsaxWifiSquare: ImageVector? = null

View File

@ -0,0 +1,78 @@
package dev.krtirtho.spotube.resources.iconsax
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
val Iconsax.PhosphorDatabaseDuotone: ImageVector
get() {
if (_PhosphorDatabaseDuotone != null) {
return _PhosphorDatabaseDuotone!!
}
_PhosphorDatabaseDuotone = ImageVector.Builder(
name = "PhosphorDatabaseDuotone",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 256f,
viewportHeight = 256f
).apply {
path(
fill = SolidColor(Color.Black),
fillAlpha = 0.2f,
strokeAlpha = 0.2f
) {
moveTo(216f, 80f)
curveToRelative(0f, 26.51f, -39.4f, 48f, -88f, 48f)
reflectiveCurveTo(40f, 106.51f, 40f, 80f)
reflectiveCurveToRelative(39.4f, -48f, 88f, -48f)
reflectiveCurveTo(216f, 53.49f, 216f, 80f)
close()
}
path(fill = SolidColor(Color.Black)) {
moveTo(128f, 24f)
curveTo(74.17f, 24f, 32f, 48.6f, 32f, 80f)
verticalLineToRelative(96f)
curveToRelative(0f, 31.4f, 42.17f, 56f, 96f, 56f)
reflectiveCurveToRelative(96f, -24.6f, 96f, -56f)
lineTo(224f, 80f)
curveTo(224f, 48.6f, 181.83f, 24f, 128f, 24f)
close()
moveTo(208f, 128f)
curveToRelative(0f, 9.62f, -7.88f, 19.43f, -21.61f, 26.92f)
curveTo(170.93f, 163.35f, 150.19f, 168f, 128f, 168f)
reflectiveCurveToRelative(-42.93f, -4.65f, -58.39f, -13.08f)
curveTo(55.88f, 147.43f, 48f, 137.62f, 48f, 128f)
lineTo(48f, 111.36f)
curveToRelative(17.06f, 15f, 46.23f, 24.64f, 80f, 24.64f)
reflectiveCurveToRelative(62.94f, -9.68f, 80f, -24.64f)
close()
moveTo(69.61f, 53.08f)
curveTo(85.07f, 44.65f, 105.81f, 40f, 128f, 40f)
reflectiveCurveToRelative(42.93f, 4.65f, 58.39f, 13.08f)
curveTo(200.12f, 60.57f, 208f, 70.38f, 208f, 80f)
reflectiveCurveToRelative(-7.88f, 19.43f, -21.61f, 26.92f)
curveTo(170.93f, 115.35f, 150.19f, 120f, 128f, 120f)
reflectiveCurveToRelative(-42.93f, -4.65f, -58.39f, -13.08f)
curveTo(55.88f, 99.43f, 48f, 89.62f, 48f, 80f)
reflectiveCurveTo(55.88f, 60.57f, 69.61f, 53.08f)
close()
moveTo(186.39f, 202.92f)
curveTo(170.93f, 211.35f, 150.19f, 216f, 128f, 216f)
reflectiveCurveToRelative(-42.93f, -4.65f, -58.39f, -13.08f)
curveTo(55.88f, 195.43f, 48f, 185.62f, 48f, 176f)
lineTo(48f, 159.36f)
curveToRelative(17.06f, 15f, 46.23f, 24.64f, 80f, 24.64f)
reflectiveCurveToRelative(62.94f, -9.68f, 80f, -24.64f)
lineTo(208f, 176f)
curveTo(208f, 185.62f, 200.12f, 195.43f, 186.39f, 202.92f)
close()
}
}.build()
return _PhosphorDatabaseDuotone!!
}
@Suppress("ObjectPropertyName")
private var _PhosphorDatabaseDuotone: ImageVector? = null