diff --git a/composeApp/src/androidMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.android.kt b/composeApp/src/androidMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.android.kt
index cfab3bd0..64a95118 100644
--- a/composeApp/src/androidMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.android.kt
+++ b/composeApp/src/androidMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.android.kt
@@ -16,6 +16,7 @@ actual object StreamBadgeSettingsStorage {
private const val legacyDebridPreferencesName = "nuvio_debrid_settings"
private const val streamBadgeRulesKey = "stream_badge_rules"
private const val showFileSizeBadgesKey = "show_file_size_badges"
+ private const val showAddonLogoKey = "show_addon_logo"
private const val streamBadgePlacementKey = "stream_badge_placement"
private const val legacyDebridStreamBadgeRulesKey = "debrid_stream_badge_rules"
@@ -41,6 +42,12 @@ actual object StreamBadgeSettingsStorage {
saveBoolean(showFileSizeBadgesKey, enabled)
}
+ actual fun loadShowAddonLogo(): Boolean? = loadBoolean(showAddonLogoKey)
+
+ actual fun saveShowAddonLogo(enabled: Boolean) {
+ saveBoolean(showAddonLogoKey, enabled)
+ }
+
actual fun loadStreamBadgePlacement(): String? = loadString(streamBadgePlacementKey)
actual fun saveStreamBadgePlacement(placement: String) {
diff --git a/composeApp/src/commonMain/composeResources/values-pl/strings.xml b/composeApp/src/commonMain/composeResources/values-pl/strings.xml
index 3e487c29..f179fcf5 100644
--- a/composeApp/src/commonMain/composeResources/values-pl/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values-pl/strings.xml
@@ -1456,4 +1456,7 @@
Torrenty
Usenet
Web
+ Logo dodatku
+ Pokazuj logo i nazwę dodatku obok źródeł.
+ Wyświetlanie
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 582b500a..be681d8d 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -681,6 +681,9 @@
Fusion Style
Size badges
Show file size badges in stream results and player source panels.
+ Addon logo
+ Show addon logo and name next to stream sources.
+ Display
Badge position
Choose whether Fusion and size badges appear above or below stream cards.
Badge position
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt
index d5fb310d..5d0f8cf3 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt
@@ -463,6 +463,15 @@ internal fun settingsSearchEntries(
val playbackSubtitleRendering = stringResource(Res.string.settings_playback_section_subtitle_rendering)
val playbackSkipSegments = stringResource(Res.string.settings_playback_section_skip_segments)
val playbackNextEpisode = stringResource(Res.string.settings_playback_section_next_episode)
+ addRow(
+ page = SettingsPage.Streams,
+ key = "stream-addon-logo",
+ title = stringResource(Res.string.settings_stream_addon_logo_title),
+ description = stringResource(Res.string.settings_stream_addon_logo_description),
+ pageLabel = streamsPage,
+ section = stringResource(Res.string.settings_stream_display_section),
+ icon = Icons.Rounded.Style,
+ )
addRow(
page = SettingsPage.Streams,
key = "stream-size-badges",
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt
index 7075eb1a..7943b55a 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt
@@ -87,6 +87,9 @@ import nuvio.composeapp.generated.resources.settings_stream_badge_urls_title
import nuvio.composeapp.generated.resources.settings_stream_badges_section
import nuvio.composeapp.generated.resources.settings_stream_size_badges_description
import nuvio.composeapp.generated.resources.settings_stream_size_badges_title
+import nuvio.composeapp.generated.resources.settings_stream_addon_logo_title
+import nuvio.composeapp.generated.resources.settings_stream_addon_logo_description
+import nuvio.composeapp.generated.resources.settings_stream_display_section
import org.jetbrains.compose.resources.stringResource
internal fun LazyListScope.streamsSettingsContent(isTablet: Boolean) {
@@ -129,6 +132,21 @@ internal fun LazyListScope.streamsSettingsContent(isTablet: Boolean) {
}
}
+ SettingsSection(
+ title = stringResource(Res.string.settings_stream_display_section),
+ isTablet = isTablet,
+ ) {
+ SettingsGroup(isTablet = isTablet) {
+ SettingsSwitchRow(
+ title = stringResource(Res.string.settings_stream_addon_logo_title),
+ description = stringResource(Res.string.settings_stream_addon_logo_description),
+ checked = currentSettings.showAddonLogo,
+ isTablet = isTablet,
+ onCheckedChange = StreamBadgeSettingsRepository::setShowAddonLogo,
+ )
+ }
+ }
+
if (showBadgeImportDialog) {
BadgeUrlManagerDialog(
currentRules = currentRules,
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt
index c48690d4..397d26ad 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt
@@ -15,6 +15,7 @@ import kotlinx.serialization.json.Json
data class StreamBadgeSettingsUiState(
val rules: StreamBadgeRules = StreamBadgeRules(),
val showFileSizeBadges: Boolean = true,
+ val showAddonLogo: Boolean = false,
val badgePlacement: StreamBadgePlacement = StreamBadgePlacement.BOTTOM,
)
@@ -36,6 +37,7 @@ object StreamBadgeSettingsRepository {
private var hasLoaded = false
private var streamBadgeRules = StreamBadgeRules()
private var showFileSizeBadges = true
+ private var showAddonLogo = false
private var badgePlacement = StreamBadgePlacement.BOTTOM
fun ensureLoaded() {
@@ -51,6 +53,7 @@ object StreamBadgeSettingsRepository {
hasLoaded = false
streamBadgeRules = StreamBadgeRules()
showFileSizeBadges = true
+ showAddonLogo = false
badgePlacement = StreamBadgePlacement.BOTTOM
_uiState.value = StreamBadgeSettingsUiState()
}
@@ -133,6 +136,14 @@ object StreamBadgeSettingsRepository {
StreamBadgeSettingsStorage.saveShowFileSizeBadges(enabled)
}
+ fun setShowAddonLogo(enabled: Boolean) {
+ ensureLoaded()
+ if (showAddonLogo == enabled) return
+ showAddonLogo = enabled
+ publish()
+ StreamBadgeSettingsStorage.saveShowAddonLogo(enabled)
+ }
+
fun setBadgePlacement(placement: StreamBadgePlacement) {
ensureLoaded()
if (badgePlacement == placement) return
@@ -151,6 +162,7 @@ object StreamBadgeSettingsRepository {
}
streamBadgeRules = storedRules ?: legacyRules ?: StreamBadgeRules()
showFileSizeBadges = StreamBadgeSettingsStorage.loadShowFileSizeBadges() ?: true
+ showAddonLogo = StreamBadgeSettingsStorage.loadShowAddonLogo() ?: false
badgePlacement = StreamBadgeSettingsStorage.loadStreamBadgePlacement()
?.let { storedPlacement ->
StreamBadgePlacement.entries.firstOrNull { placement ->
@@ -169,6 +181,7 @@ object StreamBadgeSettingsRepository {
_uiState.value = StreamBadgeSettingsUiState(
rules = streamBadgeRules,
showFileSizeBadges = showFileSizeBadges,
+ showAddonLogo = showAddonLogo,
badgePlacement = badgePlacement,
)
}
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.kt
index 5df55453..abd6dffe 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.kt
@@ -7,6 +7,8 @@ internal expect object StreamBadgeSettingsStorage {
fun saveStreamBadgeRules(rules: String)
fun loadShowFileSizeBadges(): Boolean?
fun saveShowFileSizeBadges(enabled: Boolean)
+ fun loadShowAddonLogo(): Boolean?
+ fun saveShowAddonLogo(enabled: Boolean)
fun loadStreamBadgePlacement(): String?
fun saveStreamBadgePlacement(placement: String)
fun loadLegacyDebridStreamBadgeRules(): String?
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamModels.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamModels.kt
index 7a8406c3..58a70141 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamModels.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamModels.kt
@@ -17,6 +17,7 @@ data class StreamItem(
val sourceName: String? = null,
val addonName: String,
val addonId: String,
+ val addonLogo: String? = null,
val behaviorHints: StreamBehaviorHints = StreamBehaviorHints(),
val clientResolve: StreamClientResolve? = null,
val debridCacheStatus: StreamDebridCacheStatus? = null,
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamParser.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamParser.kt
index 9a6aa866..a27033ed 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamParser.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamParser.kt
@@ -18,6 +18,7 @@ object StreamParser {
payload: String,
addonName: String,
addonId: String,
+ addonLogo: String? = null,
): List {
val root = json.parseToJsonElement(payload).jsonObject
val streamsArray = root["streams"] as? JsonArray ?: return emptyList()
@@ -46,6 +47,7 @@ object StreamParser {
sources = obj.stringList("sources"),
addonName = addonName,
addonId = addonId,
+ addonLogo = addonLogo,
clientResolve = clientResolve,
behaviorHints = StreamBehaviorHints(
bingeGroup = hintsObj?.string("bingeGroup"),
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt
index bc7bc787..49fc361a 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt
@@ -456,6 +456,7 @@ object StreamsRepository {
payload = payload,
addonName = displayName,
addonId = addon.addonId,
+ addonLogo = addon.manifest.logoUrl,
)
}.fold(
onSuccess = { streams ->
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt
index 0f6281e2..c31ff887 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt
@@ -833,6 +833,7 @@ internal fun StreamList(
debridEnabled = debridEnabled,
appendInstantServiceToDefaultName = appendInstantServiceToDefaultName,
showFileSizeBadges = streamBadgeSettings.showFileSizeBadges,
+ showAddonLogo = streamBadgeSettings.showAddonLogo,
badgePlacement = streamBadgeSettings.badgePlacement,
onStreamSelected = onStreamSelected,
onStreamLongPress = onStreamLongPress,
@@ -860,6 +861,7 @@ private fun LazyListScope.streamSection(
debridEnabled: Boolean,
appendInstantServiceToDefaultName: Boolean,
showFileSizeBadges: Boolean,
+ showAddonLogo: Boolean,
badgePlacement: StreamBadgePlacement,
onStreamSelected: (stream: StreamItem, resumePositionMs: Long?, resumeProgressFraction: Float?) -> Unit,
onStreamLongPress: (StreamItem) -> Unit,
@@ -907,6 +909,7 @@ private fun LazyListScope.streamSection(
enabled = stream.isSelectableForPlayback(debridEnabled),
appendInstantServiceToDefaultName = appendInstantServiceToDefaultName,
showFileSizeBadges = showFileSizeBadges,
+ showAddonLogo = showAddonLogo,
badgePlacement = badgePlacement,
onClick = {
if (stream.isSelectableForPlayback(debridEnabled)) {
@@ -1014,6 +1017,7 @@ private fun StreamCard(
enabled: Boolean,
appendInstantServiceToDefaultName: Boolean,
showFileSizeBadges: Boolean,
+ showAddonLogo: Boolean,
badgePlacement: StreamBadgePlacement,
onClick: () -> Unit,
onLongClick: (() -> Unit)? = null,
@@ -1040,7 +1044,7 @@ private fun StreamCard(
onLongClick = onLongClick,
)
.padding(14.dp),
- verticalAlignment = Alignment.Top,
+ verticalAlignment = Alignment.CenterVertically,
) {
Column(modifier = Modifier.weight(1f)) {
if (hasBadges && badgePlacement == StreamBadgePlacement.TOP) {
@@ -1079,6 +1083,31 @@ private fun StreamCard(
)
}
}
+
+ if (showAddonLogo) {
+ Spacer(modifier = Modifier.width(12.dp))
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ if (!stream.addonLogo.isNullOrBlank()) {
+ AsyncImage(
+ model = stream.addonLogo,
+ contentDescription = stream.addonName,
+ modifier = Modifier
+ .size(28.dp)
+ .clip(RoundedCornerShape(6.dp)),
+ contentScale = ContentScale.Fit,
+ )
+ }
+ Spacer(modifier = Modifier.height(2.dp))
+ Text(
+ text = stream.addonName,
+ style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp),
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ maxLines = 1,
+ )
+ }
+ }
}
}
diff --git a/composeApp/src/iosMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.ios.kt b/composeApp/src/iosMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.ios.kt
index 716304d8..8dbfc035 100644
--- a/composeApp/src/iosMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.ios.kt
+++ b/composeApp/src/iosMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsStorage.ios.kt
@@ -13,6 +13,7 @@ import platform.Foundation.NSUserDefaults
actual object StreamBadgeSettingsStorage {
private const val streamBadgeRulesKey = "stream_badge_rules"
private const val showFileSizeBadgesKey = "show_file_size_badges"
+ private const val showAddonLogoKey = "show_addon_logo"
private const val streamBadgePlacementKey = "stream_badge_placement"
private const val legacyDebridStreamBadgeRulesKey = "debrid_stream_badge_rules"
private val syncKeys = listOf(streamBadgeRulesKey, showFileSizeBadgesKey, streamBadgePlacementKey)
@@ -29,6 +30,12 @@ actual object StreamBadgeSettingsStorage {
saveBoolean(showFileSizeBadgesKey, enabled)
}
+ actual fun loadShowAddonLogo(): Boolean? = loadBoolean(showAddonLogoKey)
+
+ actual fun saveShowAddonLogo(enabled: Boolean) {
+ saveBoolean(showAddonLogoKey, enabled)
+ }
+
actual fun loadStreamBadgePlacement(): String? = loadString(streamBadgePlacementKey)
actual fun saveStreamBadgePlacement(placement: String) {