feat: adding cotnributors page.

This commit is contained in:
tapframe 2026-04-18 23:56:35 +05:30
parent d9fbcdb9fb
commit 49c3329526
7 changed files with 1095 additions and 7 deletions

View file

@ -89,6 +89,20 @@ abstract class GenerateRuntimeConfigsTask : DefaultTask() {
""".trimMargin() """.trimMargin()
) )
} }
outDir.resolve("com/nuvio/app/features/settings").apply {
mkdirs()
resolve("CommunityConfig.kt").writeText(
"""
|package com.nuvio.app.features.settings
|
|object CommunityConfig {
| const val DONATIONS_BASE_URL = "${props.getProperty("DONATIONS_BASE_URL", "")}"
| const val DONATIONS_DONATE_URL = "${props.getProperty("DONATIONS_DONATE_URL", "")}"
|}
""".trimMargin()
)
}
} }
} }

View file

@ -134,6 +134,7 @@ import com.nuvio.app.features.settings.ContinueWatchingSettingsScreen
import com.nuvio.app.features.settings.AddonsSettingsScreen import com.nuvio.app.features.settings.AddonsSettingsScreen
import com.nuvio.app.features.settings.PluginsSettingsScreen import com.nuvio.app.features.settings.PluginsSettingsScreen
import com.nuvio.app.features.settings.AccountSettingsScreen import com.nuvio.app.features.settings.AccountSettingsScreen
import com.nuvio.app.features.settings.SupportersContributorsSettingsScreen
import com.nuvio.app.features.settings.ThemeSettingsRepository import com.nuvio.app.features.settings.ThemeSettingsRepository
import com.nuvio.app.features.collection.CollectionManagementScreen import com.nuvio.app.features.collection.CollectionManagementScreen
import com.nuvio.app.features.collection.CollectionEditorScreen import com.nuvio.app.features.collection.CollectionEditorScreen
@ -215,6 +216,9 @@ object PluginsSettingsRoute
@Serializable @Serializable
object AccountSettingsRoute object AccountSettingsRoute
@Serializable
object SupportersContributorsSettingsRoute
@Serializable @Serializable
object CollectionsRoute object CollectionsRoute
@ -953,6 +957,9 @@ private fun MainAppContent(
} }
}, },
onAccountSettingsClick = { navController.navigate(AccountSettingsRoute) }, onAccountSettingsClick = { navController.navigate(AccountSettingsRoute) },
onSupportersContributorsSettingsClick = {
navController.navigate(SupportersContributorsSettingsRoute)
},
onCollectionsSettingsClick = { navController.navigate(CollectionsRoute) }, onCollectionsSettingsClick = { navController.navigate(CollectionsRoute) },
onFolderClick = { collectionId, folderId -> onFolderClick = { collectionId, folderId ->
navController.navigate(FolderDetailRoute(collectionId = collectionId, folderId = folderId)) navController.navigate(FolderDetailRoute(collectionId = collectionId, folderId = folderId))
@ -1558,6 +1565,15 @@ private fun MainAppContent(
onBack = onBack, onBack = onBack,
) )
} }
composable<SupportersContributorsSettingsRoute> { backStackEntry ->
val onBack = rememberGuardedPopBackStack(
navController = navController,
backStackEntry = backStackEntry,
)
SupportersContributorsSettingsScreen(
onBack = onBack,
)
}
composable<CollectionsRoute> { backStackEntry -> composable<CollectionsRoute> { backStackEntry ->
val onBack = rememberGuardedPopBackStack( val onBack = rememberGuardedPopBackStack(
navController = navController, navController = navController,
@ -1823,6 +1839,7 @@ private fun AppTabHost(
onAddonsSettingsClick: () -> Unit = {}, onAddonsSettingsClick: () -> Unit = {},
onPluginsSettingsClick: () -> Unit = {}, onPluginsSettingsClick: () -> Unit = {},
onAccountSettingsClick: () -> Unit = {}, onAccountSettingsClick: () -> Unit = {},
onSupportersContributorsSettingsClick: () -> Unit = {},
onCollectionsSettingsClick: () -> Unit = {}, onCollectionsSettingsClick: () -> Unit = {},
onFolderClick: ((collectionId: String, folderId: String) -> Unit)? = null, onFolderClick: ((collectionId: String, folderId: String) -> Unit)? = null,
onInitialHomeContentRendered: () -> Unit = {}, onInitialHomeContentRendered: () -> Unit = {},
@ -1872,6 +1889,7 @@ private fun AppTabHost(
onAddonsClick = onAddonsSettingsClick, onAddonsClick = onAddonsSettingsClick,
onPluginsClick = onPluginsSettingsClick, onPluginsClick = onPluginsSettingsClick,
onAccountClick = onAccountSettingsClick, onAccountClick = onAccountSettingsClick,
onSupportersContributorsClick = onSupportersContributorsSettingsClick,
onCollectionsClick = onCollectionsSettingsClick, onCollectionsClick = onCollectionsSettingsClick,
) )
} }

View file

@ -40,7 +40,9 @@ internal fun LazyListScope.accountSettingsContent(
} }
@Composable @Composable
private fun AccountSettingsBody(isTablet: Boolean) { private fun AccountSettingsBody(
isTablet: Boolean,
) {
val authState by AuthRepository.state.collectAsStateWithLifecycle() val authState by AuthRepository.state.collectAsStateWithLifecycle()
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
var showDeleteConfirm by remember { mutableStateOf(false) } var showDeleteConfirm by remember { mutableStateOf(false) }

View file

@ -2,6 +2,7 @@ package com.nuvio.app.features.settings
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.AccountCircle import androidx.compose.material.icons.rounded.AccountCircle
import androidx.compose.material.icons.rounded.Info
import androidx.compose.material.icons.rounded.Notifications import androidx.compose.material.icons.rounded.Notifications
import androidx.compose.material.icons.rounded.Settings import androidx.compose.material.icons.rounded.Settings
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
@ -12,6 +13,7 @@ internal enum class SettingsCategory(
) { ) {
Account("Account", Icons.Rounded.AccountCircle), Account("Account", Icons.Rounded.AccountCircle),
General("General", Icons.Rounded.Settings), General("General", Icons.Rounded.Settings),
About("About", Icons.Rounded.Info),
} }
internal enum class SettingsPage( internal enum class SettingsPage(
@ -29,6 +31,11 @@ internal enum class SettingsPage(
category = SettingsCategory.Account, category = SettingsCategory.Account,
parentPage = Root, parentPage = Root,
), ),
SupportersContributors(
title = "Supporters & Contributors",
category = SettingsCategory.About,
parentPage = Root,
),
Playback( Playback(
title = "Playback", title = "Playback",
category = SettingsCategory.General, category = SettingsCategory.General,

View file

@ -7,6 +7,8 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.AccountCircle import androidx.compose.material.icons.rounded.AccountCircle
import androidx.compose.material.icons.rounded.CloudDownload import androidx.compose.material.icons.rounded.CloudDownload
import androidx.compose.material.icons.rounded.Extension import androidx.compose.material.icons.rounded.Extension
import androidx.compose.material.icons.rounded.Favorite
import androidx.compose.material.icons.rounded.Info
import androidx.compose.material.icons.rounded.Link import androidx.compose.material.icons.rounded.Link
import androidx.compose.material.icons.rounded.Notifications import androidx.compose.material.icons.rounded.Notifications
import androidx.compose.material.icons.rounded.Palette import androidx.compose.material.icons.rounded.Palette
@ -27,11 +29,13 @@ internal fun LazyListScope.settingsRootContent(
onContentDiscoveryClick: () -> Unit, onContentDiscoveryClick: () -> Unit,
onIntegrationsClick: () -> Unit, onIntegrationsClick: () -> Unit,
onTraktClick: () -> Unit, onTraktClick: () -> Unit,
onSupportersContributorsClick: () -> Unit,
onDownloadsClick: () -> Unit, onDownloadsClick: () -> Unit,
onAccountClick: () -> Unit, onAccountClick: () -> Unit,
onSwitchProfileClick: (() -> Unit)? = null, onSwitchProfileClick: (() -> Unit)? = null,
showAccountSection: Boolean = true, showAccountSection: Boolean = true,
showGeneralSection: Boolean = true, showGeneralSection: Boolean = true,
showAboutSection: Boolean = true,
) { ) {
if (showAccountSection) { if (showAccountSection) {
item { item {
@ -127,15 +131,44 @@ internal fun LazyListScope.settingsRootContent(
} }
} }
} }
if (showAboutSection) {
item {
SettingsSection(
title = "ABOUT",
isTablet = isTablet,
) {
SettingsGroup(isTablet = isTablet) {
SettingsNavigationRow(
title = "Supporters & Contributors",
description = "See cross-app contributors and the supporters backing Nuvio.",
icon = Icons.Rounded.Favorite,
isTablet = isTablet,
onClick = onSupportersContributorsClick,
)
}
}
}
}
item { item {
Text( androidx.compose.foundation.layout.Column(
text = "Version ${AppVersionConfig.VERSION_NAME} (${AppVersionConfig.VERSION_CODE})",
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 20.dp, vertical = if (isTablet) 20.dp else 16.dp), .padding(horizontal = 20.dp, vertical = if (isTablet) 20.dp else 16.dp),
style = MaterialTheme.typography.bodySmall, ) {
color = MaterialTheme.colorScheme.onSurfaceVariant, Text(
textAlign = TextAlign.Center, text = "Made with ❤️ by Tapframe and friends",
) modifier = Modifier.fillMaxWidth(),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
)
Text(
text = "Version ${AppVersionConfig.VERSION_NAME} (${AppVersionConfig.VERSION_CODE})",
modifier = Modifier.fillMaxWidth(),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
)
}
} }
} }

View file

@ -70,6 +70,7 @@ fun SettingsScreen(
onPluginsClick: () -> Unit = {}, onPluginsClick: () -> Unit = {},
onDownloadsClick: () -> Unit = {}, onDownloadsClick: () -> Unit = {},
onAccountClick: () -> Unit = {}, onAccountClick: () -> Unit = {},
onSupportersContributorsClick: () -> Unit = {},
onCollectionsClick: () -> Unit = {}, onCollectionsClick: () -> Unit = {},
) { ) {
BoxWithConstraints( BoxWithConstraints(
@ -188,6 +189,7 @@ fun SettingsScreen(
posterCardStyleUiState = posterCardStyleUiState, posterCardStyleUiState = posterCardStyleUiState,
onSwitchProfile = onSwitchProfile, onSwitchProfile = onSwitchProfile,
onDownloadsClick = onDownloadsClick, onDownloadsClick = onDownloadsClick,
onSupportersContributorsClick = onSupportersContributorsClick,
onCollectionsClick = onCollectionsClick, onCollectionsClick = onCollectionsClick,
) )
} else { } else {
@ -230,6 +232,7 @@ fun SettingsScreen(
onPluginsClick = onPluginsClick, onPluginsClick = onPluginsClick,
onDownloadsClick = onDownloadsClick, onDownloadsClick = onDownloadsClick,
onAccountClick = onAccountClick, onAccountClick = onAccountClick,
onSupportersContributorsClick = onSupportersContributorsClick,
onCollectionsClick = onCollectionsClick, onCollectionsClick = onCollectionsClick,
) )
} }
@ -276,6 +279,7 @@ private fun MobileSettingsScreen(
onPluginsClick: () -> Unit = {}, onPluginsClick: () -> Unit = {},
onDownloadsClick: () -> Unit = {}, onDownloadsClick: () -> Unit = {},
onAccountClick: () -> Unit = {}, onAccountClick: () -> Unit = {},
onSupportersContributorsClick: () -> Unit = {},
onCollectionsClick: () -> Unit = {}, onCollectionsClick: () -> Unit = {},
) { ) {
NuvioScreen { NuvioScreen {
@ -296,6 +300,7 @@ private fun MobileSettingsScreen(
onContentDiscoveryClick = { onPageChange(SettingsPage.ContentDiscovery) }, onContentDiscoveryClick = { onPageChange(SettingsPage.ContentDiscovery) },
onIntegrationsClick = { onPageChange(SettingsPage.Integrations) }, onIntegrationsClick = { onPageChange(SettingsPage.Integrations) },
onTraktClick = { onPageChange(SettingsPage.TraktAuthentication) }, onTraktClick = { onPageChange(SettingsPage.TraktAuthentication) },
onSupportersContributorsClick = onSupportersContributorsClick,
onDownloadsClick = onDownloadsClick, onDownloadsClick = onDownloadsClick,
onAccountClick = onAccountClick, onAccountClick = onAccountClick,
onSwitchProfileClick = onSwitchProfile, onSwitchProfileClick = onSwitchProfile,
@ -303,6 +308,9 @@ private fun MobileSettingsScreen(
SettingsPage.Account -> accountSettingsContent( SettingsPage.Account -> accountSettingsContent(
isTablet = false, isTablet = false,
) )
SettingsPage.SupportersContributors -> supportersContributorsContent(
isTablet = false,
)
SettingsPage.Playback -> playbackSettingsContent( SettingsPage.Playback -> playbackSettingsContent(
isTablet = false, isTablet = false,
showLoadingOverlay = showLoadingOverlay, showLoadingOverlay = showLoadingOverlay,
@ -421,6 +429,7 @@ private fun TabletSettingsScreen(
posterCardStyleUiState: PosterCardStyleUiState, posterCardStyleUiState: PosterCardStyleUiState,
onSwitchProfile: (() -> Unit)? = null, onSwitchProfile: (() -> Unit)? = null,
onDownloadsClick: () -> Unit = {}, onDownloadsClick: () -> Unit = {},
onSupportersContributorsClick: () -> Unit = {},
onCollectionsClick: () -> Unit = {}, onCollectionsClick: () -> Unit = {},
) { ) {
var selectedCategory by rememberSaveable { mutableStateOf(SettingsCategory.General.name) } var selectedCategory by rememberSaveable { mutableStateOf(SettingsCategory.General.name) }
@ -508,15 +517,20 @@ private fun TabletSettingsScreen(
onContentDiscoveryClick = { openInlinePage(SettingsPage.ContentDiscovery) }, onContentDiscoveryClick = { openInlinePage(SettingsPage.ContentDiscovery) },
onIntegrationsClick = { openInlinePage(SettingsPage.Integrations) }, onIntegrationsClick = { openInlinePage(SettingsPage.Integrations) },
onTraktClick = { openInlinePage(SettingsPage.TraktAuthentication) }, onTraktClick = { openInlinePage(SettingsPage.TraktAuthentication) },
onSupportersContributorsClick = { openInlinePage(SettingsPage.SupportersContributors) },
onDownloadsClick = onDownloadsClick, onDownloadsClick = onDownloadsClick,
onAccountClick = { openInlinePage(SettingsPage.Account) }, onAccountClick = { openInlinePage(SettingsPage.Account) },
onSwitchProfileClick = onSwitchProfile, onSwitchProfileClick = onSwitchProfile,
showAccountSection = activeCategory == SettingsCategory.Account, showAccountSection = activeCategory == SettingsCategory.Account,
showGeneralSection = activeCategory == SettingsCategory.General, showGeneralSection = activeCategory == SettingsCategory.General,
showAboutSection = activeCategory == SettingsCategory.About,
) )
SettingsPage.Account -> accountSettingsContent( SettingsPage.Account -> accountSettingsContent(
isTablet = true, isTablet = true,
) )
SettingsPage.SupportersContributors -> supportersContributorsContent(
isTablet = true,
)
SettingsPage.Playback -> playbackSettingsContent( SettingsPage.Playback -> playbackSettingsContent(
isTablet = true, isTablet = true,
showLoadingOverlay = showLoadingOverlay, showLoadingOverlay = showLoadingOverlay,