Skip to content

Commit 71ec133

Browse files
committed
feat: add contributor name and email settings, update ShareSavedLyricsDialog for anonymous contributions
1 parent 65d4ea3 commit 71ec133

9 files changed

Lines changed: 253 additions & 19 deletions

File tree

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ dependencies {
307307

308308
fullImplementation(libs.sentry.android)
309309

310-
debugImplementation(libs.leak.canary)
310+
// debugImplementation(libs.leak.canary)
311311
}
312312
aboutLibraries {
313313
export {

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

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,15 +1100,16 @@ class DataStoreManager(
11001100
const val LOCAL_PLAYLIST_FILTER_OLDER_FIRST = "older_first"
11011101
const val LOCAL_PLAYLIST_FILTER_NEWER_FIRST = "newer_first"
11021102
const val LOCAL_PLAYLIST_FILTER_TITLE = "title"
1103+
val YOUTUBE_SUBTITLE_LANGUAGE = stringPreferencesKey("youtube_subtitle_language")
1104+
val HELP_BUILD_LYRICS_DATABASE = stringPreferencesKey("help_build_lyrics_database")
1105+
val CONTRIBUTOR_NAME = stringPreferencesKey("contributor_name")
1106+
val CONTRIBUTOR_EMAIL = stringPreferencesKey("contributor_email")
11031107

11041108
// Proxy type
11051109
enum class ProxyType {
11061110
PROXY_TYPE_HTTP,
11071111
PROXY_TYPE_SOCKS,
11081112
}
1109-
1110-
val YOUTUBE_SUBTITLE_LANGUAGE = stringPreferencesKey("youtube_subtitle_language")
1111-
val HELP_BUILD_LYRICS_DATABASE = stringPreferencesKey("help_build_lyrics_database")
11121113
}
11131114

11141115
val helpBuildLyricsDatabase: Flow<String> =
@@ -1129,4 +1130,30 @@ class DataStoreManager(
11291130
}
11301131
}
11311132
}
1133+
1134+
val contributorName: Flow<String> =
1135+
settingsDataStore.data.map { preferences ->
1136+
preferences[CONTRIBUTOR_NAME] ?: ""
1137+
}
1138+
1139+
val contributorEmail: Flow<String> =
1140+
settingsDataStore.data.map { preferences ->
1141+
preferences[CONTRIBUTOR_EMAIL] ?: ""
1142+
}
1143+
1144+
suspend fun setContributorLyricsDatabase(
1145+
contributor: Pair<String, String>?, // contributor name and email, null if anonymous
1146+
) {
1147+
withContext(Dispatchers.IO) {
1148+
settingsDataStore.edit { settings ->
1149+
if (contributor == null) {
1150+
settings[CONTRIBUTOR_NAME] = ""
1151+
settings[CONTRIBUTOR_EMAIL] = ""
1152+
} else {
1153+
settings[CONTRIBUTOR_NAME] = contributor.first
1154+
settings[CONTRIBUTOR_EMAIL] = contributor.second
1155+
}
1156+
}
1157+
}
1158+
}
11321159
}

app/src/main/java/com/maxrave/simpmusic/ui/component/ShareSavedLyricsDialog.kt

Lines changed: 114 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
11
package com.maxrave.simpmusic.ui.component
22

3+
import androidx.compose.animation.AnimatedVisibility
4+
import androidx.compose.animation.fadeIn
5+
import androidx.compose.animation.fadeOut
6+
import androidx.compose.animation.slideInHorizontally
7+
import androidx.compose.animation.slideOutHorizontally
8+
import androidx.compose.foundation.clickable
39
import androidx.compose.foundation.layout.Column
10+
import androidx.compose.foundation.layout.Row
11+
import androidx.compose.foundation.layout.Spacer
12+
import androidx.compose.foundation.layout.height
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.layout.width
415
import androidx.compose.material3.AlertDialog
16+
import androidx.compose.material3.Checkbox
517
import androidx.compose.material3.ExperimentalMaterial3Api
18+
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
19+
import androidx.compose.material3.OutlinedTextField
620
import androidx.compose.material3.Text
721
import androidx.compose.material3.TextButton
822
import androidx.compose.runtime.Composable
9-
import androidx.compose.ui.platform.LocalUriHandler
23+
import androidx.compose.runtime.CompositionLocalProvider
24+
import androidx.compose.runtime.getValue
25+
import androidx.compose.runtime.mutableStateOf
26+
import androidx.compose.runtime.remember
27+
import androidx.compose.runtime.setValue
28+
import androidx.compose.ui.Alignment
29+
import androidx.compose.ui.Modifier
1030
import androidx.compose.ui.res.stringResource
1131
import androidx.compose.ui.text.LinkAnnotation
1232
import androidx.compose.ui.text.SpanStyle
1333
import androidx.compose.ui.text.TextLinkStyles
1434
import androidx.compose.ui.text.buildAnnotatedString
1535
import androidx.compose.ui.text.withLink
36+
import androidx.compose.ui.unit.Dp
37+
import androidx.compose.ui.unit.dp
38+
import androidx.compose.ui.unit.sp
1639
import androidx.compose.ui.window.DialogProperties
1740
import com.maxrave.simpmusic.R
1841
import com.maxrave.simpmusic.ui.theme.md_theme_dark_primary
@@ -22,9 +45,20 @@ import com.maxrave.simpmusic.ui.theme.typo
2245
@ExperimentalMaterial3Api
2346
fun ShareSavedLyricsDialog(
2447
onDismissRequest: () -> Unit,
25-
onConfirm: () -> Unit,
48+
onConfirm: (
49+
contributor: Pair<String, String>?,
50+
) -> Unit, // contributor name and email, null if anonymous
2651
) {
27-
val uriHandler = LocalUriHandler.current
52+
var useAnonymous by remember {
53+
mutableStateOf(true)
54+
}
55+
var contributorName by remember {
56+
mutableStateOf("")
57+
}
58+
var contributorEmail by remember {
59+
mutableStateOf("")
60+
}
61+
2862
AlertDialog(
2963
properties =
3064
DialogProperties(
@@ -36,7 +70,14 @@ fun ShareSavedLyricsDialog(
3670
},
3771
confirmButton = {
3872
TextButton(onClick = {
39-
onConfirm.invoke()
73+
onDismissRequest.invoke()
74+
onConfirm(
75+
if (useAnonymous) {
76+
null
77+
} else {
78+
Pair(contributorName, contributorEmail)
79+
},
80+
)
4081
}) {
4182
Text(
4283
stringResource(R.string.ok),
@@ -81,6 +122,75 @@ fun ShareSavedLyricsDialog(
81122
},
82123
style = typo.bodySmall,
83124
)
125+
Spacer(Modifier.height(8.dp))
126+
AnimatedVisibility(
127+
modifier =
128+
Modifier.padding(
129+
vertical = 12.dp,
130+
),
131+
visible = !useAnonymous,
132+
enter = fadeIn() + slideInHorizontally(),
133+
exit = fadeOut() + slideOutHorizontally(),
134+
) {
135+
Column {
136+
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides Dp.Unspecified) {
137+
OutlinedTextField(
138+
value = contributorName,
139+
textStyle = typo.bodySmall,
140+
onValueChange = { contributorName = it },
141+
label = {
142+
Text(
143+
stringResource(R.string.contributor_name),
144+
style =
145+
typo.labelSmall.copy(
146+
fontSize = 8.sp,
147+
),
148+
)
149+
},
150+
placeholder = { Text(stringResource(R.string.contributor_name), style = typo.bodySmall) },
151+
singleLine = true,
152+
)
153+
Spacer(Modifier.height(8.dp))
154+
OutlinedTextField(
155+
value = contributorEmail,
156+
textStyle = typo.bodySmall,
157+
onValueChange = { contributorEmail = it },
158+
label = {
159+
Text(
160+
stringResource(R.string.contributor_email),
161+
style =
162+
typo.labelSmall.copy(
163+
fontSize = 8.sp,
164+
),
165+
)
166+
},
167+
placeholder = { Text(stringResource(R.string.contributor_email), style = typo.bodySmall) },
168+
singleLine = true,
169+
isError = contributorEmail.isNotEmpty() && !contributorEmail.contains("@"),
170+
)
171+
Spacer(Modifier.height(8.dp))
172+
}
173+
}
174+
}
175+
Row(
176+
modifier =
177+
Modifier.clickable {
178+
useAnonymous = !useAnonymous
179+
},
180+
verticalAlignment = Alignment.CenterVertically,
181+
) {
182+
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides Dp.Unspecified) {
183+
Checkbox(
184+
checked = useAnonymous,
185+
onCheckedChange = { useAnonymous = it },
186+
)
187+
}
188+
Spacer(Modifier.width(8.dp))
189+
Text(
190+
stringResource(R.string.use_anonymous),
191+
style = typo.bodySmall,
192+
)
193+
}
84194
}
85195
},
86196
)

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,10 @@ fun HomeScreen(
252252
isDismissOnly = true,
253253
)
254254
},
255-
onConfirm = {
256-
sharedViewModel.onDoneRequestingShareLyrics()
255+
onConfirm = { contributor ->
256+
sharedViewModel.onDoneRequestingShareLyrics(
257+
contributor,
258+
)
257259
},
258260
)
259261
}

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

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ fun SettingScreen(
197197
val isHasApiKey by viewModel.isHasApiKey.collectAsStateWithLifecycle()
198198
val useAITranslation by viewModel.useAITranslation.collectAsStateWithLifecycle()
199199
val customModelId by viewModel.customModelId.collectAsStateWithLifecycle()
200+
val helpBuildLyricsDatabase by viewModel.helpBuildLyricsDatabase.collectAsStateWithLifecycle()
201+
val contributor by viewModel.contributor.collectAsStateWithLifecycle()
200202

201203
var checkForUpdateSubtitle by rememberSaveable {
202204
mutableStateOf("")
@@ -359,6 +361,7 @@ fun SettingScreen(
359361
state.selectOne?.getSelected() ?: "US",
360362
)
361363
},
364+
dismiss = context.getString(R.string.cancel),
362365
),
363366
)
364367
},
@@ -705,6 +708,7 @@ fun SettingScreen(
705708
},
706709
)
707710
},
711+
dismiss = context.getString(R.string.cancel),
708712
),
709713
)
710714
},
@@ -761,6 +765,7 @@ fun SettingScreen(
761765
context.getString(R.string.change) to { state ->
762766
viewModel.setTranslationLanguage(state.textField?.value ?: "")
763767
},
768+
dismiss = context.getString(R.string.cancel),
764769
),
765770
)
766771
},
@@ -786,17 +791,69 @@ fun SettingScreen(
786791
context.getString(R.string.change) to { state ->
787792
viewModel.setYoutubeSubtitleLanguage(state.textField?.value ?: "")
788793
},
794+
dismiss = context.getString(R.string.cancel),
789795
),
790796
)
791797
},
792798
)
793-
794-
val helpBuildLyricsDatabase by viewModel.helpBuildLyricsDatabase.map { it == TRUE }.collectAsStateWithLifecycle(initialValue = false)
795799
SettingItem(
796800
title = stringResource(R.string.help_build_lyrics_database),
797801
subtitle = stringResource(R.string.help_build_lyrics_database_description),
798802
switch = (helpBuildLyricsDatabase to { viewModel.setHelpBuildLyricsDatabase(it) }),
799803
)
804+
SettingItem(
805+
title = stringResource(R.string.contributor_name),
806+
subtitle = contributor.first.ifEmpty { stringResource(R.string.anonymous) },
807+
isEnable = helpBuildLyricsDatabase,
808+
onClick = {
809+
viewModel.setAlertData(
810+
SettingAlertState(
811+
title = context.getString(R.string.contributor_name),
812+
textField =
813+
SettingAlertState.TextFieldData(
814+
label = context.getString(R.string.contributor_name),
815+
value = "",
816+
),
817+
message = "",
818+
confirm =
819+
context.getString(R.string.set) to { state ->
820+
viewModel.setContributorName(state.textField?.value ?: "")
821+
},
822+
dismiss = context.getString(R.string.cancel),
823+
),
824+
)
825+
},
826+
)
827+
SettingItem(
828+
title = stringResource(R.string.contributor_email),
829+
subtitle = contributor.second.ifEmpty { stringResource(R.string.anonymous) },
830+
isEnable = helpBuildLyricsDatabase,
831+
onClick = {
832+
viewModel.setAlertData(
833+
SettingAlertState(
834+
title = context.getString(R.string.contributor_email),
835+
textField =
836+
SettingAlertState.TextFieldData(
837+
label = context.getString(R.string.contributor_email),
838+
value = "",
839+
verifyCodeBlock = {
840+
if (it.isNotEmpty()) {
841+
(it.contains("@")) to context.getString(R.string.invalid)
842+
} else {
843+
true to ""
844+
}
845+
},
846+
),
847+
message = "",
848+
confirm =
849+
context.getString(R.string.set) to { state ->
850+
viewModel.setContributorEmail(state.textField?.value ?: "")
851+
},
852+
dismiss = context.getString(R.string.cancel),
853+
),
854+
)
855+
},
856+
)
800857
Text(
801858
buildAnnotatedString {
802859
append(stringResource(R.string.lyrics_database_description))
@@ -848,6 +905,7 @@ fun SettingScreen(
848905
},
849906
)
850907
},
908+
dismiss = context.getString(R.string.cancel),
851909
),
852910
)
853911
},
@@ -872,6 +930,7 @@ fun SettingScreen(
872930
context.getString(R.string.set) to { state ->
873931
viewModel.setAIApiKey(state.textField?.value ?: "")
874932
},
933+
dismiss = context.getString(R.string.cancel),
875934
),
876935
)
877936
},
@@ -896,6 +955,7 @@ fun SettingScreen(
896955
context.getString(R.string.set) to { state ->
897956
viewModel.setCustomModelId(state.textField?.value ?: "")
898957
},
958+
dismiss = context.getString(R.string.cancel),
899959
),
900960
)
901961
},

0 commit comments

Comments
 (0)