Skip to content

Commit 8c62fc3

Browse files
authored
[release] 🔧 5.7.1
2 parents 7d22d9b + c1aeab4 commit 8c62fc3

File tree

40 files changed

+1023
-603
lines changed

40 files changed

+1023
-603
lines changed

.github/workflows/beta.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88

99
jobs:
1010
build:
11-
if: startsWith(github.event.head_commit.message, '[beta]') || contains(github.event.head_commit.message, 'Weblate')
11+
if: github.event_name == 'workflow_dispatch' || startsWith(github.event.head_commit.message, '[beta]')
1212
runs-on: ubuntu-latest
1313
env:
1414
VERSION: $( echo ${{ github.event.head_commit.id }} | cut -c1-7 )

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ permissions:
1111

1212
jobs:
1313
build:
14-
if: startsWith(github.event.head_commit.message, '[release]')
14+
if: github.event_name == 'workflow_dispatch' || startsWith(github.event.head_commit.message, '[release]')
1515
runs-on: ubuntu-latest
1616
env:
1717
VERSION: $( echo ${{ github.event.head_commit.id }} | cut -c1-7 )

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 5.7.1
4+
- Fixed auto lyrics fetching issues
5+
- Fixed miscellaneous song sync bugs
6+
- Updated Lyrics Customisation UI
7+
- Updated Share Cards UI
8+
39
## 5.7.0
410
- Added support for TTML (Syllable Synced) Lyrics
511
- Improved Synced Lyrics Animation

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ plugins {
2525
}
2626

2727
val appName = "Rush"
28-
val appVersionName = "5.7.0"
29-
val appVersionCode = 5700
28+
val appVersionName = "5.7.1"
29+
val appVersionCode = 5710
3030

3131
val publicGeniusApiToken = "\"qLSDtgIqHgzGNjOFUmdOxJKGJOg5RIAPzOKTfrs7rNxqYXwfdSh9HTHMJUs2X27Y\""
3232

app/src/main/assets/changelog.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
[
2+
{
3+
"version": "5.7.1",
4+
"changes": [
5+
"Fixed auto lyrics fetching issues",
6+
"Fixed miscellaneous song sync bugs",
7+
"Updated Lyrics Customisation UI",
8+
"Updated Share Cards UI"
9+
]
10+
},
211
{
312
"version": "5.7.0",
413
"changes": [

app/src/main/java/com/shub39/rush/app/App.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import androidx.navigation.compose.composable
3535
import androidx.navigation.compose.rememberNavController
3636
import coil3.ImageLoader
3737
import com.shub39.rush.billing.PaywallPage
38-
import com.shub39.rush.presentation.ChangelogDialog
38+
import com.shub39.rush.presentation.ChangelogSheet
3939
import com.shub39.rush.presentation.components.RushTheme
4040
import com.shub39.rush.presentation.lyrics.LyricsGraph
4141
import com.shub39.rush.presentation.onboarding.Onboarding
@@ -92,7 +92,7 @@ fun App() {
9292
CompositionLocalProvider(LocalCoilImageLoader provides koinInject<ImageLoader>()) {
9393
RushTheme(theme = globalState.theme) {
9494
if (globalState.currentChangelog != null) {
95-
ChangelogDialog(
95+
ChangelogSheet(
9696
currentLog = globalState.currentChangelog!!,
9797
onDismissRequest = { globalVM.onAction(GlobalAction.DismissChangelog) },
9898
)
@@ -123,12 +123,14 @@ fun App() {
123123
composable<Route.LyricsGraph> {
124124
val lyricsVM: LyricsVM = koinViewModel()
125125
val lyricsState by lyricsVM.state.collectAsStateWithLifecycle()
126+
val playbackInfo by lyricsVM.playbackInfo.collectAsStateWithLifecycle()
126127

127128
LyricsGraph(
128129
notificationAccess = globalState.notificationAccess,
129130
lyricsState = lyricsState,
130131
lyricsAction = lyricsVM::onAction,
131132
onDismiss = { navController.navigateUp() },
133+
playbackInfo = playbackInfo,
132134
onShare = {
133135
navController.navigate(Route.SharePage) { launchSingleTop = true }
134136
},

app/src/main/java/com/shub39/rush/data/listener/MediaListenerImpl.kt

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ import com.shub39.rush.data.listener.MediaListenerImpl.songInfoFlow
3131
import com.shub39.rush.data.listener.MediaListenerImpl.songPositionFlow
3232
import kotlinx.coroutines.CoroutineScope
3333
import kotlinx.coroutines.Dispatchers
34+
import kotlinx.coroutines.Job
35+
import kotlinx.coroutines.channels.BufferOverflow
3436
import kotlinx.coroutines.delay
3537
import kotlinx.coroutines.flow.MutableSharedFlow
38+
import kotlinx.coroutines.isActive
3639
import kotlinx.coroutines.launch
3740

3841
/**
@@ -63,10 +66,14 @@ object MediaListenerImpl {
6366
private val internalCallbacks = mutableMapOf<MediaSession.Token, MediaController.Callback>()
6467
private var initialised = false
6568
private var coroutineScope = CoroutineScope(Dispatchers.IO)
69+
private var positionUpdateJob: Job? = null
6670

67-
val playbackSpeedFlow: MutableSharedFlow<Float> = MutableSharedFlow()
68-
val songInfoFlow: MutableSharedFlow<Pair<String, String>> = MutableSharedFlow()
69-
val songPositionFlow: MutableSharedFlow<Long> = MutableSharedFlow()
71+
val playbackSpeedFlow: MutableSharedFlow<Float> =
72+
MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
73+
val songInfoFlow: MutableSharedFlow<Pair<String, String>> =
74+
MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
75+
val songPositionFlow: MutableSharedFlow<Long> =
76+
MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
7077

7178
fun startListening(context: Context) {
7279
try {
@@ -132,6 +139,8 @@ object MediaListenerImpl {
132139
delay(2000)
133140
setActiveMediaSession(controller)
134141
}
142+
} else if (isActive(controller.playbackState)) {
143+
setActiveMediaSession(controller)
135144
}
136145

137146
if (internalCallbacks.containsKey(controller.sessionToken)) {
@@ -182,13 +191,41 @@ object MediaListenerImpl {
182191
if (isActive(state)) {
183192
setActiveMediaSession(controller)
184193
} else {
185-
coroutineScope.launch { playbackSpeedFlow.emit(0f) }
194+
stopPositionUpdates()
195+
coroutineScope.launch {
196+
playbackSpeedFlow.emit(0f)
197+
state?.position?.let { songPositionFlow.emit(it) }
198+
}
186199
}
187200
}
188201

189202
private fun setActiveMediaSession(newActive: MediaController) {
190203
activeMediaController = newActive
191204
updateMetadata(newActive, newActive.metadata)
205+
startPositionUpdates()
206+
}
207+
208+
private fun startPositionUpdates() {
209+
positionUpdateJob?.cancel()
210+
positionUpdateJob =
211+
coroutineScope.launch {
212+
while (isActive) {
213+
activeMediaController?.let { controller ->
214+
if (isActive(controller.playbackState)) {
215+
val position = controller.playbackState?.position ?: 0L
216+
val speed = controller.playbackState?.playbackSpeed ?: 1f
217+
songPositionFlow.emit(position)
218+
playbackSpeedFlow.emit(speed)
219+
}
220+
}
221+
delay(1000)
222+
}
223+
}
224+
}
225+
226+
private fun stopPositionUpdates() {
227+
positionUpdateJob?.cancel()
228+
positionUpdateJob = null
192229
}
193230

194231
private fun updateMetadata(controller: MediaController, metadata: MediaMetadata?) {

app/src/main/java/com/shub39/rush/presentation/ChangelogDialog.kt

Lines changed: 0 additions & 91 deletions
This file was deleted.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright (C) 2026 Shubham Gorai
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
package com.shub39.rush.presentation
18+
19+
import androidx.compose.foundation.background
20+
import androidx.compose.foundation.layout.Arrangement
21+
import androidx.compose.foundation.layout.Box
22+
import androidx.compose.foundation.layout.Column
23+
import androidx.compose.foundation.layout.PaddingValues
24+
import androidx.compose.foundation.layout.Spacer
25+
import androidx.compose.foundation.layout.fillMaxWidth
26+
import androidx.compose.foundation.layout.height
27+
import androidx.compose.foundation.layout.padding
28+
import androidx.compose.foundation.layout.size
29+
import androidx.compose.foundation.lazy.LazyColumn
30+
import androidx.compose.foundation.lazy.itemsIndexed
31+
import androidx.compose.material3.Button
32+
import androidx.compose.material3.ExperimentalMaterial3Api
33+
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
34+
import androidx.compose.material3.Icon
35+
import androidx.compose.material3.ListItem
36+
import androidx.compose.material3.MaterialShapes
37+
import androidx.compose.material3.MaterialTheme
38+
import androidx.compose.material3.Text
39+
import androidx.compose.material3.toShape
40+
import androidx.compose.runtime.Composable
41+
import androidx.compose.ui.Alignment
42+
import androidx.compose.ui.Modifier
43+
import androidx.compose.ui.draw.clip
44+
import androidx.compose.ui.res.painterResource
45+
import androidx.compose.ui.res.stringResource
46+
import androidx.compose.ui.unit.dp
47+
import com.shub39.rush.R
48+
import com.shub39.rush.app.VersionEntry
49+
import com.shub39.rush.presentation.components.RushBottomSheet
50+
51+
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
52+
@Composable
53+
fun ChangelogSheet(
54+
modifier: Modifier = Modifier,
55+
currentLog: VersionEntry,
56+
onDismissRequest: () -> Unit,
57+
) {
58+
RushBottomSheet(onDismissRequest = onDismissRequest, modifier = modifier, padding = 0.dp) {
59+
Column(
60+
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
61+
verticalArrangement = Arrangement.spacedBy(4.dp),
62+
) {
63+
Box(
64+
contentAlignment = Alignment.Center,
65+
modifier =
66+
Modifier.size(48.dp)
67+
.background(
68+
color = MaterialTheme.colorScheme.primaryContainer,
69+
shape = MaterialShapes.Pill.toShape(),
70+
),
71+
) {
72+
Icon(
73+
painter = painterResource(R.drawable.settings),
74+
contentDescription = null,
75+
tint = MaterialTheme.colorScheme.onPrimaryContainer,
76+
)
77+
}
78+
79+
Column {
80+
Text(
81+
text = stringResource(R.string.whats_changed),
82+
style =
83+
MaterialTheme.typography.headlineSmall.copy(fontFamily = flexFontEmphasis()),
84+
)
85+
Text(
86+
text = currentLog.version,
87+
style =
88+
MaterialTheme.typography.titleMedium.copy(fontFamily = flexFontRounded()),
89+
)
90+
}
91+
92+
LazyColumn(
93+
verticalArrangement = Arrangement.spacedBy(2.dp),
94+
contentPadding = PaddingValues(vertical = 16.dp),
95+
) {
96+
itemsIndexed(currentLog.changes) { index, change ->
97+
val shape =
98+
when {
99+
currentLog.changes.size == 1 -> detachedItemShape()
100+
index == 0 -> leadingItemShape()
101+
index == currentLog.changes.size - 1 -> endItemShape()
102+
else -> middleItemShape()
103+
}
104+
105+
ListItem(
106+
colors = listItemColors(),
107+
modifier = Modifier.clip(shape),
108+
headlineContent = { Text(text = change) },
109+
)
110+
}
111+
}
112+
113+
Button(onClick = onDismissRequest, modifier = Modifier.fillMaxWidth()) {
114+
Text(text = stringResource(R.string.done))
115+
}
116+
117+
Spacer(modifier = Modifier.height(16.dp))
118+
}
119+
}
120+
}

0 commit comments

Comments
 (0)