Skip to content

Commit 65d4ea3

Browse files
committed
feat: implement help build lyrics database
1 parent ea420fd commit 65d4ea3

7 files changed

Lines changed: 191 additions & 0 deletions

File tree

app/src/main/java/com/maxrave/simpmusic/data/dataStore/DataStoreManager.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,5 +1108,25 @@ class DataStoreManager(
11081108
}
11091109

11101110
val YOUTUBE_SUBTITLE_LANGUAGE = stringPreferencesKey("youtube_subtitle_language")
1111+
val HELP_BUILD_LYRICS_DATABASE = stringPreferencesKey("help_build_lyrics_database")
1112+
}
1113+
1114+
val helpBuildLyricsDatabase: Flow<String> =
1115+
settingsDataStore.data.map { preferences ->
1116+
preferences[HELP_BUILD_LYRICS_DATABASE] ?: FALSE
1117+
}
1118+
1119+
suspend fun setHelpBuildLyricsDatabase(help: Boolean) {
1120+
withContext(Dispatchers.IO) {
1121+
if (help) {
1122+
settingsDataStore.edit { settings ->
1123+
settings[HELP_BUILD_LYRICS_DATABASE] = TRUE
1124+
}
1125+
} else {
1126+
settingsDataStore.edit { settings ->
1127+
settings[HELP_BUILD_LYRICS_DATABASE] = FALSE
1128+
}
1129+
}
1130+
}
11111131
}
11121132
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.maxrave.simpmusic.ui.component
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.material3.AlertDialog
5+
import androidx.compose.material3.ExperimentalMaterial3Api
6+
import androidx.compose.material3.Text
7+
import androidx.compose.material3.TextButton
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.platform.LocalUriHandler
10+
import androidx.compose.ui.res.stringResource
11+
import androidx.compose.ui.text.LinkAnnotation
12+
import androidx.compose.ui.text.SpanStyle
13+
import androidx.compose.ui.text.TextLinkStyles
14+
import androidx.compose.ui.text.buildAnnotatedString
15+
import androidx.compose.ui.text.withLink
16+
import androidx.compose.ui.window.DialogProperties
17+
import com.maxrave.simpmusic.R
18+
import com.maxrave.simpmusic.ui.theme.md_theme_dark_primary
19+
import com.maxrave.simpmusic.ui.theme.typo
20+
21+
@Composable
22+
@ExperimentalMaterial3Api
23+
fun ShareSavedLyricsDialog(
24+
onDismissRequest: () -> Unit,
25+
onConfirm: () -> Unit,
26+
) {
27+
val uriHandler = LocalUriHandler.current
28+
AlertDialog(
29+
properties =
30+
DialogProperties(
31+
dismissOnBackPress = false,
32+
dismissOnClickOutside = false,
33+
),
34+
onDismissRequest = {
35+
onDismissRequest.invoke()
36+
},
37+
confirmButton = {
38+
TextButton(onClick = {
39+
onConfirm.invoke()
40+
}) {
41+
Text(
42+
stringResource(R.string.ok),
43+
style = typo.bodySmall,
44+
)
45+
}
46+
},
47+
dismissButton = {
48+
TextButton(onClick = {
49+
onDismissRequest.invoke()
50+
}) {
51+
Text(
52+
stringResource(id = R.string.later),
53+
style = typo.bodySmall,
54+
)
55+
}
56+
},
57+
title = {
58+
Text(
59+
stringResource(R.string.help_build_lyrics_database),
60+
style = typo.labelSmall,
61+
)
62+
},
63+
text = {
64+
Column {
65+
Text(
66+
stringResource(R.string.help_build_lyrics_database_description),
67+
style = typo.bodySmall,
68+
)
69+
Text(
70+
buildAnnotatedString {
71+
append(stringResource(R.string.lyrics_database_description))
72+
append(" ")
73+
withLink(
74+
LinkAnnotation.Url(
75+
"https://github.com/maxrave-dev/lyrics",
76+
TextLinkStyles(style = SpanStyle(color = md_theme_dark_primary)),
77+
),
78+
) {
79+
append("https://github.com/maxrave-dev/lyrics")
80+
}
81+
},
82+
style = typo.bodySmall,
83+
)
84+
}
85+
},
86+
)
87+
}

app/src/main/java/com/maxrave/simpmusic/ui/screen/home/HomeScreen.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import com.maxrave.simpmusic.R
7878
import com.maxrave.simpmusic.common.CHART_SUPPORTED_COUNTRY
7979
import com.maxrave.simpmusic.common.Config
8080
import com.maxrave.simpmusic.common.LIMIT_CACHE_SIZE.data
81+
import com.maxrave.simpmusic.data.dataStore.DataStoreManager
8182
import com.maxrave.simpmusic.data.model.browse.album.Track
8283
import com.maxrave.simpmusic.data.model.explore.mood.Mood
8384
import com.maxrave.simpmusic.data.model.home.HomeItem
@@ -103,6 +104,7 @@ import com.maxrave.simpmusic.ui.component.MusixmatchCaptchaWebView
103104
import com.maxrave.simpmusic.ui.component.QuickPicksItem
104105
import com.maxrave.simpmusic.ui.component.ReviewDialog
105106
import com.maxrave.simpmusic.ui.component.RippleIconButton
107+
import com.maxrave.simpmusic.ui.component.ShareSavedLyricsDialog
106108
import com.maxrave.simpmusic.ui.theme.typo
107109
import com.maxrave.simpmusic.viewModel.HomeViewModel
108110
import com.maxrave.simpmusic.viewModel.SharedViewModel
@@ -146,11 +148,16 @@ fun HomeScreen(
146148
val shouldShowLogInAlert by viewModel.showLogInAlert.collectAsState()
147149

148150
val openAppTime by sharedViewModel.openAppTime.collectAsState()
151+
val shareLyricsPermissions by sharedViewModel.shareSavedLyrics.collectAsState()
152+
149153
val musixmatchCaptchaRequired by sharedViewModel.showMusixmatchCaptchaWebView.collectAsState()
150154

151155
var showReviewDialog by rememberSaveable {
152156
mutableStateOf(false)
153157
}
158+
var showRequestShareLyricsPermissions by rememberSaveable {
159+
mutableStateOf(false)
160+
}
154161

155162
val dataSyncId by viewModel.dataSyncId.collectAsState()
156163
val youTubeCookie by viewModel.youTubeCookie.collectAsState()
@@ -197,6 +204,8 @@ fun HomeScreen(
197204
LaunchedEffect(openAppTime) {
198205
if (openAppTime >= 10 && openAppTime % 10 == 0 && openAppTime <= 50) {
199206
showReviewDialog = true
207+
} else if ((openAppTime == 1 || openAppTime % 15 == 0) && openAppTime <= 60 && shareLyricsPermissions != DataStoreManager.TRUE) {
208+
showRequestShareLyricsPermissions = true
200209
}
201210
}
202211

@@ -235,6 +244,20 @@ fun HomeScreen(
235244
)
236245
}
237246

247+
if (showRequestShareLyricsPermissions) {
248+
ShareSavedLyricsDialog(
249+
onDismissRequest = {
250+
showRequestShareLyricsPermissions = false
251+
sharedViewModel.onDoneReview(
252+
isDismissOnly = true,
253+
)
254+
},
255+
onConfirm = {
256+
sharedViewModel.onDoneRequestingShareLyrics()
257+
},
258+
)
259+
}
260+
238261
if (shouldShowLogInAlert) {
239262
var doNotShowAgain by rememberSaveable {
240263
mutableStateOf(false)

app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,29 @@ fun SettingScreen(
790790
)
791791
},
792792
)
793+
794+
val helpBuildLyricsDatabase by viewModel.helpBuildLyricsDatabase.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = false)
795+
SettingItem(
796+
title = stringResource(R.string.help_build_lyrics_database),
797+
subtitle = stringResource(R.string.help_build_lyrics_database_description),
798+
switch = (helpBuildLyricsDatabase to { viewModel.setHelpBuildLyricsDatabase(it) }),
799+
)
800+
Text(
801+
buildAnnotatedString {
802+
append(stringResource(R.string.lyrics_database_description))
803+
append(" ")
804+
withLink(
805+
LinkAnnotation.Url(
806+
"https://github.com/maxrave-dev/lyrics",
807+
TextLinkStyles(style = SpanStyle(color = md_theme_dark_primary)),
808+
),
809+
) {
810+
append("https://github.com/maxrave-dev/lyrics")
811+
}
812+
},
813+
style = typo.bodySmall,
814+
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp),
815+
)
793816
}
794817
}
795818
item(key = "AI") {

app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ class SettingsViewModel(
141141
private val _youtubeSubtitleLanguage = MutableStateFlow<String>("")
142142
val youtubeSubtitleLanguage: StateFlow<String> = _youtubeSubtitleLanguage
143143

144+
private var _helpBuildLyricsDatabase: MutableStateFlow<String> = MutableStateFlow("")
145+
val helpBuildLyricsDatabase: StateFlow<String> = _helpBuildLyricsDatabase
146+
144147
private var _alertData: MutableStateFlow<SettingAlertState?> = MutableStateFlow(null)
145148
val alertData: StateFlow<SettingAlertState?> = _alertData
146149

@@ -158,6 +161,11 @@ class SettingsViewModel(
158161
private var _killServiceOnExit: MutableStateFlow<String?> = MutableStateFlow(null)
159162
val killServiceOnExit: StateFlow<String?> = _killServiceOnExit
160163

164+
init {
165+
getYoutubeSubtitleLanguage()
166+
getHelpBuildLyricsDatabase()
167+
}
168+
161169
fun getAudioSessionId() = simpleMediaServiceHandler.player.audioSessionId
162170

163171
fun getData() {
@@ -1247,6 +1255,21 @@ class SettingsViewModel(
12471255
getYoutubeSubtitleLanguage()
12481256
}
12491257
}
1258+
1259+
fun getHelpBuildLyricsDatabase() {
1260+
viewModelScope.launch {
1261+
dataStoreManager.helpBuildLyricsDatabase.collect { helpBuildLyricsDatabase ->
1262+
_helpBuildLyricsDatabase.emit(helpBuildLyricsDatabase)
1263+
}
1264+
}
1265+
}
1266+
1267+
fun setHelpBuildLyricsDatabase(help: Boolean) {
1268+
viewModelScope.launch {
1269+
dataStoreManager.setHelpBuildLyricsDatabase(help)
1270+
getHelpBuildLyricsDatabase()
1271+
}
1272+
}
12501273
}
12511274

12521275
data class SettingsStorageSectionFraction(

app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ class SharedViewModel(
186186
val likeStatus: StateFlow<Boolean> = _likeStatus
187187

188188
val openAppTime: StateFlow<Int> = dataStoreManager.openAppTime.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), 0)
189+
val shareSavedLyrics: StateFlow<String> =
190+
dataStoreManager.helpBuildLyricsDatabase.stateIn(
191+
viewModelScope,
192+
SharingStarted.WhileSubscribed(5000L),
193+
FALSE,
194+
)
189195

190196
init {
191197
mainRepository.initYouTube(viewModelScope)
@@ -1384,6 +1390,12 @@ class SharedViewModel(
13841390
}
13851391
}
13861392

1393+
fun onDoneRequestingShareLyrics() {
1394+
viewModelScope.launch {
1395+
dataStoreManager.setHelpBuildLyricsDatabase(true)
1396+
}
1397+
}
1398+
13871399
fun setBitmap(bitmap: ImageBitmap?) {
13881400
_nowPlayingScreenData.update {
13891401
it.copy(bitmap = bitmap)

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@
198198
<string name="skip_sponsor_part_of_video">Skip sponsor part of video</string>
199199
<string name="customactivityoncrash_error_activity_error_occurred_explanation">An unexpected error occurred. Sorry for the inconvenience.</string>
200200
<string name="customactivityoncrash_error_activity_restart_app">Restart app</string>
201+
<string name="help_build_lyrics_database">Help SimpMusic lyrics build the lyrics database</string>
202+
<string name="help_build_lyrics_database_description">Send your saved lyrics to SimpMusic lyrics\'s database</string>
203+
<string name="lyrics_database_description">We are building our own lyrics database for SimpMusic and other YouTube clients for non-commercial purposes, open-sourced at</string>
201204
<string name="customactivityoncrash_error_activity_close_app">Close app</string>
202205
<string name="customactivityoncrash_error_activity_error_details">Error details</string>
203206
<string name="customactivityoncrash_error_activity_error_details_title">Error details</string>

0 commit comments

Comments
 (0)