Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.theveloper.pixelplay.presentation.components.external.ExternalPlayerO
import com.theveloper.pixelplay.ui.theme.PixelPlayTheme
import android.content.Intent.EXTRA_STREAM
import androidx.media3.common.util.UnstableApi
import com.google.android.gms.wearable.AppTheme
import com.theveloper.pixelplay.data.preferences.AppThemeMode
import com.theveloper.pixelplay.data.preferences.ThemePreferencesRepository
import javax.inject.Inject
Expand Down Expand Up @@ -49,9 +50,15 @@ class ExternalPlayerActivity : ComponentActivity() {
val useDarkTheme = when (appThemeMode) {
AppThemeMode.DARK -> true
AppThemeMode.LIGHT -> false
AppThemeMode.PURE_DARK -> true
else -> systemDarkTheme
}
PixelPlayTheme(darkTheme = useDarkTheme) {
val isOled = when(appThemeMode){
AppThemeMode.PURE_DARK -> true
else -> false
}
PixelPlayTheme(darkTheme = useDarkTheme, pureDark = isOled) {

ExternalPlayerOverlay(
playerViewModel = playerViewModel,
onDismiss = { finish() },
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/java/com/theveloper/pixelplay/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ class MainActivity : ComponentActivity() {
AppThemeMode.LIGHT -> false
else -> systemDarkTheme
}
val usePureDark = when(appThemeMode){
AppThemeMode.PURE_DARK -> true
else -> false
}
val isSetupComplete by mainViewModel.isSetupComplete.collectAsStateWithLifecycle()

// Crash report dialog state
Expand Down Expand Up @@ -256,7 +260,8 @@ class MainActivity : ComponentActivity() {
}

PixelPlayTheme(
darkTheme = useDarkTheme
darkTheme = useDarkTheme,
pureDark = usePureDark
) {
var contentVisible by remember { mutableStateOf(false) }
val contentAlpha by animateFloatAsState(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ class ThemePreferencesRepository @Inject constructor(
val ALBUM_ART_PALETTE_STYLE = stringPreferencesKey("album_art_palette_style_v1")
val ALBUM_ART_COLOR_ACCURACY = intPreferencesKey("album_art_color_accuracy_v1")
val APP_THEME_MODE = stringPreferencesKey("app_theme_mode")

}

val appThemeModeFlow: Flow<String> = dataStore.data.map { preferences ->
preferences[Keys.APP_THEME_MODE] ?: AppThemeMode.FOLLOW_SYSTEM
}


val playerThemePreferenceFlow: Flow<String> = dataStore.data.map { preferences ->
preferences[Keys.PLAYER_THEME_PREFERENCE] ?: ThemePreference.ALBUM_ART
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ object AppThemeMode {
const val FOLLOW_SYSTEM = "follow_system"
const val LIGHT = "light"
const val DARK = "dark"

const val PURE_DARK = "puredark"
}

/**
Expand Down Expand Up @@ -85,6 +87,8 @@ constructor(
// Removed
val PLAYER_THEME_PREFERENCE = stringPreferencesKey("player_theme_preference_v2")
val ALBUM_ART_PALETTE_STYLE = stringPreferencesKey("album_art_palette_style_v1")
val ALBUM_ART_PALETTE_PURE_DARK = booleanPreferencesKey("album_art_palette_pure_dark")

val APP_THEME_MODE = stringPreferencesKey("app_theme_mode")
val FAVORITE_SONG_IDS = stringSetPreferencesKey("favorite_song_ids")
val USER_PLAYLISTS = stringPreferencesKey("user_playlists_json_v1")
Expand Down Expand Up @@ -235,6 +239,9 @@ constructor(
val REPLAYGAIN_USE_ALBUM_GAIN = booleanPreferencesKey("replaygain_use_album_gain")
}

val albumArtPalettePureDarkFlow: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.ALBUM_ART_PALETTE_PURE_DARK] ?: false }


val appRebrandDialogShownFlow: Flow<Boolean> =
dataStore.data.map { preferences ->
preferences[PreferencesKeys.APP_REBRAND_DIALOG_SHOWN] ?: false
Expand Down Expand Up @@ -323,6 +330,10 @@ constructor(
}
}

suspend fun setAlbumArtPalettePureDark(enabled: Boolean) {
dataStore.edit { it[PreferencesKeys.ALBUM_ART_PALETTE_PURE_DARK] = enabled }
}

suspend fun addCustomGenre(genre: String, iconResId: Int? = null) {
dataStore.edit { preferences ->
val currentGenres = preferences[PreferencesKeys.CUSTOM_GENRES] ?: emptySet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SwitchDefaults
import androidx.compose.ui.draw.clip
import com.theveloper.pixelplay.ui.theme.LocalPixelPlayPureDark

import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape
import androidx.compose.foundation.BorderStroke

@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
Expand Down Expand Up @@ -90,29 +92,44 @@ fun LyricsFloatingToolbar(
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
ToggleSegmentButton(
modifier = Modifier.weight(1f).height(50.dp),
modifier = Modifier
.weight(1f)
.height(50.dp),
active = showSyncedLyrics,
enabled = hasSyncedLyrics,
activeColor = accentColor,
inactiveColor = backgroundColor,
inactiveColor = if(LocalPixelPlayPureDark.current) {
Color.Transparent
}else{backgroundColor},
activeContentColor = onAccentColor,
inactiveContentColor = onBackgroundColor,
activeCornerRadius = 50.dp,
onClick = { onShowSyncedLyricsChange(true) },
text = stringResource(R.string.presentation_batch_g_lyrics_mode_synced)
text = stringResource(R.string.presentation_batch_g_lyrics_mode_synced),

border = if (!showSyncedLyrics && LocalPixelPlayPureDark.current) {
BorderStroke(1.dp, MaterialTheme.colorScheme.outline)
} else null
)

ToggleSegmentButton(
modifier = Modifier.weight(1f).height(50.dp),
modifier = Modifier
.weight(1f)
.height(50.dp),
active = !showSyncedLyrics,
enabled = true,
activeColor = accentColor,
inactiveColor = backgroundColor,
inactiveColor = if(LocalPixelPlayPureDark.current) {
Color.Transparent
}else{backgroundColor},
activeContentColor = onAccentColor,
inactiveContentColor = onBackgroundColor,
activeCornerRadius = 50.dp,
onClick = { onShowSyncedLyricsChange(false) },
text = stringResource(R.string.presentation_batch_g_lyrics_mode_static)
text = stringResource(R.string.presentation_batch_g_lyrics_mode_static),
border = if (showSyncedLyrics && LocalPixelPlayPureDark.current) {
BorderStroke(1.dp, MaterialTheme.colorScheme.outline)
} else null
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.ui.text.style.TextGeometricTransform
import androidx.compose.ui.text.style.TextOverflow
import com.theveloper.pixelplay.presentation.components.subcomps.PlayingEqIcon
import com.theveloper.pixelplay.ui.theme.LocalPixelPlayDarkTheme
import com.theveloper.pixelplay.ui.theme.LocalPixelPlayPureDark
import com.theveloper.pixelplay.utils.MultiLangRomanizer

@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -979,8 +979,8 @@ fun QueueBottomSheet(
QueueToolbarMenuButton(
text = stringResource(R.string.presentation_batch_e_action_save_as_playlist),
icon = Icons.Filled.LibraryAdd,
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
containerColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
onClick = {
isFabExpanded = false
val res = context.resources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
Expand All @@ -28,9 +30,9 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.theveloper.pixelplay.presentation.components.LocalMaterialTheme

@Composable
fun ToggleSegmentButton(
Expand All @@ -42,6 +44,7 @@ fun ToggleSegmentButton(
activeContentColor: Color = LocalMaterialTheme.current.onPrimary,
inactiveContentColor: Color = LocalMaterialTheme.current.onSurfaceVariant,
activeCornerRadius: Dp = 8.dp,
border: BorderStroke? = null,
onClick: () -> Unit,
iconId: Int,
contentDesc: String
Expand All @@ -53,6 +56,7 @@ fun ToggleSegmentButton(
activeColor = activeColor,
inactiveColor = inactiveColor,
activeCornerRadius = activeCornerRadius,
border = border,
onClick = onClick
) {
Icon(
Expand All @@ -74,6 +78,7 @@ fun ToggleSegmentButton(
activeContentColor: Color = LocalMaterialTheme.current.onPrimary,
inactiveContentColor: Color = LocalMaterialTheme.current.onSurfaceVariant,
activeCornerRadius: Dp = 8.dp,
border: BorderStroke? = null,
onClick: () -> Unit,
imageVector: ImageVector,
contentDesc: String
Expand All @@ -85,6 +90,7 @@ fun ToggleSegmentButton(
activeColor = activeColor,
inactiveColor = inactiveColor,
activeCornerRadius = activeCornerRadius,
border = border,
onClick = onClick
) {
Icon(
Expand All @@ -106,6 +112,7 @@ fun ToggleSegmentButton(
activeContentColor: Color = LocalMaterialTheme.current.onPrimary,
inactiveContentColor: Color = LocalMaterialTheme.current.primary,
activeCornerRadius: Dp = 8.dp,
border: BorderStroke? = null,
onClick: () -> Unit,
text: String
) {
Expand All @@ -116,13 +123,14 @@ fun ToggleSegmentButton(
activeColor = activeColor,
inactiveColor = inactiveColor,
activeCornerRadius = activeCornerRadius,
border = border,
onClick = onClick
) {
androidx.compose.material3.Text(
Text(
text = text,
color = if (active) activeContentColor else inactiveContentColor,
style = androidx.compose.material3.MaterialTheme.typography.bodyMedium,
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Bold
)
}
}
Expand All @@ -139,7 +147,8 @@ fun ToggleSegmentButton(
activeCornerRadius: Dp = 8.dp,
onClick: () -> Unit,
text: String,
imageVector: ImageVector
imageVector: ImageVector,
border: BorderStroke? = null,
) {
ToggleSegmentButtonContainer(
modifier = modifier,
Expand All @@ -148,7 +157,8 @@ fun ToggleSegmentButton(
activeColor = activeColor,
inactiveColor = inactiveColor,
activeCornerRadius = activeCornerRadius,
onClick = onClick
onClick = onClick,
border = border
) {
Row(
verticalAlignment = Alignment.CenterVertically,
Expand All @@ -166,13 +176,12 @@ fun ToggleSegmentButton(
text = text,
color = if (active) activeContentColor else inactiveContentColor,
style = MaterialTheme.typography.bodyMedium,
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold
fontWeight = FontWeight.Bold
)
}
}
}


@Composable
private fun ToggleSegmentButtonContainer(
modifier: Modifier,
Expand All @@ -182,30 +191,38 @@ private fun ToggleSegmentButtonContainer(
inactiveColor: Color,
activeCornerRadius: Dp,
onClick: () -> Unit,
content: @Composable () -> Unit
border: BorderStroke? = null,
content: @Composable () -> Unit,
) {
val targetBgColor = if (active) activeColor else inactiveColor
val bgColor by animateColorAsState(
targetValue = if (enabled) targetBgColor else targetBgColor.copy(alpha = 0.5f),
animationSpec = tween(durationMillis = 250),
label = ""
label = "bgColorAnimation"
)
val cornerRadius by animateDpAsState(
targetValue = if (active) activeCornerRadius else 8.dp,
animationSpec = spring(stiffness = Spring.StiffnessLow),
label = ""
label = "cornerRadiusAnimation"
)


val shape = RoundedCornerShape(cornerRadius)

Box(
modifier = modifier
.fillMaxSize()
.clip(RoundedCornerShape(cornerRadius))
.clip(shape)
.background(bgColor)
.then(
if (border != null) Modifier.border(border, shape)
else Modifier
)
.clickable(enabled = enabled, onClick = onClick),
contentAlignment = Alignment.Center
) {
Box(modifier = Modifier.graphicsLayer(alpha = if (enabled) 1f else 0.38f)) {
content()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import com.theveloper.pixelplay.presentation.viewmodel.PlayerSheetState
import com.theveloper.pixelplay.presentation.viewmodel.PlayerViewModel
import com.theveloper.pixelplay.presentation.viewmodel.StablePlayerState
import com.theveloper.pixelplay.ui.theme.LocalPixelPlayDarkTheme
import com.theveloper.pixelplay.ui.theme.LocalPixelPlayPureDark
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
Expand Down Expand Up @@ -496,10 +497,12 @@ fun UnifiedPlayerSheetV2(
val activePlayerSchemePair by playerViewModel.activePlayerColorSchemePair.collectAsStateWithLifecycle()
val themedAlbumArtUri by playerViewModel.currentThemedAlbumArtUri.collectAsStateWithLifecycle()
val isDarkTheme = LocalPixelPlayDarkTheme.current
val isPureDark = LocalPixelPlayPureDark.current
val currentSong = infrequentPlayerState.currentSong
val sheetThemeState = rememberSheetThemeState(
activePlayerSchemePair = activePlayerSchemePair,
isDarkTheme = isDarkTheme,
isPureDark = isPureDark,
playerThemePreference = playerThemePreference,
currentSong = currentSong,
themedAlbumArtUri = themedAlbumArtUri,
Expand Down
Loading