Merge pull request #1316 from skoruppa/feature/stream-addon-logo

This commit is contained in:
Nayif 2026-06-10 18:34:28 +05:30 committed by GitHub
commit f9eb536cdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 96 additions and 1 deletions

View file

@ -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) {

View file

@ -1456,4 +1456,7 @@
<string name="cloud_library_type_torrents">Torrenty</string>
<string name="cloud_library_type_usenet">Usenet</string>
<string name="cloud_library_type_web">Web</string>
<string name="settings_stream_addon_logo_title">Logo dodatku</string>
<string name="settings_stream_addon_logo_description">Pokazuj logo i nazwę dodatku obok źródeł.</string>
<string name="settings_stream_display_section">Wyświetlanie</string>
</resources>

View file

@ -681,6 +681,9 @@
<string name="settings_stream_badges_section">Fusion Style</string>
<string name="settings_stream_size_badges_title">Size badges</string>
<string name="settings_stream_size_badges_description">Show file size badges in stream results and player source panels.</string>
<string name="settings_stream_addon_logo_title">Addon logo</string>
<string name="settings_stream_addon_logo_description">Show addon logo and name next to stream sources.</string>
<string name="settings_stream_display_section">Display</string>
<string name="settings_stream_badge_position_title">Badge position</string>
<string name="settings_stream_badge_position_description">Choose whether Fusion and size badges appear above or below stream cards.</string>
<string name="settings_stream_badge_position_dialog_title">Badge position</string>

View file

@ -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",

View file

@ -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,

View file

@ -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,
)
}

View file

@ -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?

View file

@ -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,

View file

@ -18,6 +18,7 @@ object StreamParser {
payload: String,
addonName: String,
addonId: String,
addonLogo: String? = null,
): List<StreamItem> {
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"),

View file

@ -456,6 +456,7 @@ object StreamsRepository {
payload = payload,
addonName = displayName,
addonId = addon.addonId,
addonLogo = addon.manifest.logoUrl,
)
}.fold(
onSuccess = { streams ->

View file

@ -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,
)
}
}
}
}

View file

@ -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) {