Skip to content

Commit

Permalink
feat(settings): Add blur fullscreen lyrics setting
Browse files Browse the repository at this point in the history
This commit introduces a new setting to blur the background of the fullscreen lyrics screen.  The setting is added to the app's settings screen and affects the appearance of the fullscreen lyrics.  A new library `haze` is added to implement the blur effect.
  • Loading branch information
maxrave-dev committed Jan 30, 2025
1 parent 8990537 commit eda2dcc
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 564 deletions.
4 changes: 4 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ dependencies {

// Jetbrains Markdown
api(libs.markdown)

// Blur Haze
implementation(libs.haze)
implementation(libs.haze.material)
}
aboutLibraries {
prettyPrint = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,25 @@ class DataStoreManager(
}
}

val blurFullscreenLyrics =
settingsDataStore.data.map { preferences ->
preferences[BLUR_FULLSCREEN_LYRICS] ?: FALSE
}

suspend fun setBlurFullscreenLyrics(blur: Boolean) {
withContext(Dispatchers.IO) {
if (blur) {
settingsDataStore.edit { settings ->
settings[BLUR_FULLSCREEN_LYRICS] = TRUE
}
} else {
settingsDataStore.edit { settings ->
settings[BLUR_FULLSCREEN_LYRICS] = FALSE
}
}
}
}

companion object Settings {
val COOKIE = stringPreferencesKey("cookie")
val LOGGED_IN = stringPreferencesKey("logged_in")
Expand Down Expand Up @@ -751,6 +770,7 @@ class DataStoreManager(
val ENDLESS_QUEUE = stringPreferencesKey("endless_queue")
val SHOULD_SHOW_LOG_IN_REQUIRED_ALERT = stringPreferencesKey("should_show_log_in_required_alert")
val AUTO_CHECK_FOR_UPDATES = stringPreferencesKey("auto_check_for_updates")
val BLUR_FULLSCREEN_LYRICS = stringPreferencesKey("blur_fullscreen_lyrics")
const val REPEAT_MODE_OFF = "REPEAT_MODE_OFF"
const val REPEAT_ONE = "REPEAT_ONE"
const val REPEAT_ALL = "REPEAT_ALL"
Expand Down
875 changes: 461 additions & 414 deletions app/src/main/java/com/maxrave/simpmusic/ui/component/LyricsView.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ fun SettingScreen(
val proxyHost by viewModel.proxyHost.collectAsStateWithLifecycle()
val proxyPort by viewModel.proxyPort.collectAsStateWithLifecycle()
val autoCheckUpdate by viewModel.autoCheckUpdate.collectAsStateWithLifecycle()
val blurFullscreenLyrics by viewModel.blurFullscreenLyrics.collectAsStateWithLifecycle()
var checkForUpdateSubtitle by rememberSaveable {
mutableStateOf("")
}
Expand Down Expand Up @@ -269,6 +270,12 @@ fun SettingScreen(
smallSubtitle = true,
switch = (enableTranslucentNavBar to { viewModel.setTranslucentBottomBar(it) }),
)
SettingItem(
title = stringResource(R.string.blur_fullscreen_lyrics),
subtitle = stringResource(R.string.blur_fullscreen_lyrics_description),
smallSubtitle = true,
switch = (blurFullscreenLyrics to { viewModel.setBlurFullscreenLyrics(it) }),
)
}
}
item(key = "content") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ fun NowPlayingScreen(
sharedViewModel = sharedViewModel,
color = startColor.value,
navController = navController,
shouldHaze = sharedViewModel.blurFullscreenLyrics(),
) {
showFullscreenLyrics = false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ class SettingsViewModel(
val proxyPort: StateFlow<Int> = _proxyPort
private var _autoCheckUpdate = MutableStateFlow(false)
val autoCheckUpdate: StateFlow<Boolean> = _autoCheckUpdate
private var _blurFullscreenLyrics = MutableStateFlow(false)
val blurFullscreenLyrics: StateFlow<Boolean> = _blurFullscreenLyrics

private var _alertData: MutableStateFlow<SettingAlertState?> = MutableStateFlow(null)
val alertData: StateFlow<SettingAlertState?> = _alertData
Expand Down Expand Up @@ -170,11 +172,27 @@ class SettingsViewModel(
getCanvasCache()
getTranslucentBottomBar()
getAutoCheckUpdate()
getBlurFullscreenLyrics()
viewModelScope.launch {
calculateDataFraction()
}
}

private fun getBlurFullscreenLyrics() {
viewModelScope.launch {
dataStoreManager.blurFullscreenLyrics.collect { blurFullscreenLyrics ->
_blurFullscreenLyrics.value = blurFullscreenLyrics == DataStoreManager.TRUE
}
}
}

fun setBlurFullscreenLyrics(blurFullscreenLyrics: Boolean) {
viewModelScope.launch {
dataStoreManager.setBlurFullscreenLyrics(blurFullscreenLyrics)
getBlurFullscreenLyrics()
}
}

private fun getAutoCheckUpdate() {
viewModelScope.launch {
dataStoreManager.autoCheckForUpdates.collect { autoCheckUpdate ->
Expand Down
152 changes: 2 additions & 150 deletions app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -380,119 +380,6 @@ class SharedViewModel(
}
}
}
// val job2 =
// launch {
// handler.nowPlaying.collectLatest { nowPlaying ->
// Log.w("MainActivity", "nowPlaying collect $nowPlaying")
// nowPlaying?.let { now ->
// _format.value = null
// _songInfo.value = null
// _canvas.value = null
// canvasJob?.cancel()
// getSongInfo(now.mediaId)
// getSkipSegments(now.mediaId)
// basicWidget.performUpdate(
// context,
// simpleMediaServiceHandler!!,
// null,
// )
// downloadImageForWidgetJob?.cancel()
// downloadImageForWidgetJob =
// viewModelScope.launch {
// val p = getScreenSize(context)
// val widgetImageSize = p.x.coerceAtMost(p.y)
// val imageRequest =
// ImageRequest.Builder(context)
// .data(nowPlaying.mediaMetadata.artworkUri)
// .size(widgetImageSize)
// .placeholder(R.drawable.holder_video)
// .target(
// onSuccess = { drawable ->
// basicWidget.updateImage(
// context,
// drawable.toBitmap(
// widgetImageSize,
// widgetImageSize,
// ),
// )
// },
// onStart = { holder ->
// if (holder != null) {
// basicWidget.updateImage(
// context,
// holder.toBitmap(
// widgetImageSize,
// widgetImageSize,
// ),
// )
// }
// },
// onError = {
// AppCompatResources.getDrawable(
// context,
// R.drawable.holder_video,
// )
// ?.let { it1 ->
// basicWidget.updateImage(
// context,
// it1.toBitmap(
// widgetImageSize,
// widgetImageSize,
// ),
// )
// }
// },
// ).build()
// ImageLoader(context).execute(imageRequest)
// }
// }
// if (nowPlaying != null) {
// transformEmit(nowPlaying)
// val tempSong =
// simpleMediaServiceHandler!!.queueData.first()?.listTracks?.getOrNull(
// getCurrentMediaItemIndex(),
// )
// if (tempSong != null) {
// Log.d("Check tempSong", tempSong.toString())
// mainRepository.insertSong(
// tempSong.toSongEntity(),
// ).first()
// .let { id ->
// Log.d("Check insertSong", id.toString())
// }
// mainRepository.getSongById(tempSong.videoId)
// .collectLatest { songEntity ->
// _songDB.value = songEntity
// if (songEntity != null) {
// Log.w(
// "Check like",
// "SharedViewModel nowPlaying collect ${songEntity.liked}",
// )
// _liked.value = songEntity.liked
// }
// }
// mainRepository.updateSongInLibrary(
// LocalDateTime.now(),
// tempSong.videoId,
// )
// mainRepository.updateListenCount(tempSong.videoId)
// tempSong.durationSeconds?.let {
// mainRepository.updateDurationSeconds(
// it,
// tempSong.videoId,
// )
// }
// videoId.postValue(tempSong.videoId)
// transformEmit(nowPlaying)
// }
// val index = getCurrentMediaItemIndex() + 1
// Log.w("Check index", index.toString())
// val size = simpleMediaServiceHandler!!.queueData.first()?.listTracks?.size ?: 0
// Log.w("Check size", size.toString())
// Log.w("Check loadingMore", loadingMore.toString())
// }
// }
// }
val controllerJob =
launch {
Log.w(tag, "ControllerJob is running")
Expand All @@ -515,53 +402,18 @@ class SharedViewModel(
}
}
}
// val getDurationJob = launch {
// combine(nowPlayingState, mediaState){ nowPlayingState, mediaState ->
// Pair(nowPlayingState, mediaState)
// }.collectLatest {
// val nowPlaying = it.first
// val media = it.second
// if (media is SimpleMediaState.Ready && nowPlaying?.mediaItem != null) {
// if (nowPlaying.mediaItem.isSong()) {
// Log.w(tag, "Duration is ${media.duration}")
// getCanvas(nowPlaying.mediaItem.mediaId, media.duration.toInt())
// }
// getLyricsFromFormat(nowPlaying.mediaItem.mediaId, media.duration.toInt())
// }
// }
// }
// getDurationJob.join()
// val job3 =
// launch {
// handler.controlState.collectLatest { controlState ->
// _shuffleModeEnabled.value = controlState.isShuffle
// _repeatMode.value = controlState.repeatState
// isPlaying.value = controlState.isPlaying
// }
// }
// val job10 =
// launch {
// nowPlayingMediaItem.collectLatest { now ->
// Log.d(
// "Now Playing",
// now?.mediaId + now?.mediaMetadata?.title
// )
// }
// }
job1.join()
controllerJob.join()
sleepTimerJob.join()
playlistNameJob.join()
// job2.join()
// job3.join()
// nowPlayingJob.join()
// job10.join()
}
if (runBlocking { dataStoreManager.loggedIn.first() } == TRUE) {
getYouTubeLiked()
}
}

fun blurFullscreenLyrics(): Boolean = runBlocking { dataStoreManager.blurFullscreenLyrics.first() == TRUE }

private fun getLikeStatus(videoId: String?) {
viewModelScope.launch {
if (videoId != null) {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -382,4 +382,6 @@
<string name="do_not_show_again">Do not show again</string>
<string name="auto_check_for_update">Automatic check for update</string>
<string name="auto_check_for_update_description">Checking for update when you open app</string>
<string name="blur_fullscreen_lyrics">Blur fullscreen lyrics effect</string>
<string name="blur_fullscreen_lyrics_description">Blurring the background of the Fullscreen lyrics screen effect</string>
</resources>
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ koin-bom = "4.0.0-RC1"
md = "0.7.3"
store = "5.1.0-alpha05"
ui-text-android = "1.7.7"
haze = "1.3.0"

[libraries]
desugaring = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "desugaring"}
Expand Down Expand Up @@ -147,6 +148,8 @@ kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
ksoup-html = { group = "com.mohamedrejeb.ksoup", name = "ksoup-html", version.ref = "ksoup" }
ksoup-entities = { group = "com.mohamedrejeb.ksoup", name = "ksoup-entities", version.ref = "ksoup" }
markdown = { module = "org.jetbrains:markdown", version.ref = "md" }
haze = { module = "dev.chrisbanes.haze:haze", version.ref = "haze" }
haze-material = { module = "dev.chrisbanes.haze:haze-materials", version.ref = "haze" }
store = { module = "org.mobilenativefoundation.store:store5", version.ref = "store" }
# Use NewPipeExtractor from the Outertune project (Thanks to @DD3Boh)
newpipe-extractor = { module = "com.github.gechoto:NewPipeExtractor", version = "00cf7dad9e49933c7faaa382c9c7b1e7afb28a7d" }
Expand Down

0 comments on commit eda2dcc

Please sign in to comment.