Skip to content

Commit 11f7534

Browse files
authored
Added Explicit badge. (#305)
1 parent b5a4c62 commit 11f7534

4 files changed

Lines changed: 40 additions & 32 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,6 @@ testflight-reports/
6868

6969
# Downloaded binary frameworks (too large for git, see ios_build_instructions.md step 5)
7070
iosApp/Frameworks/
71+
72+
# Google Play developer-verification token (per-account, do not commit)
73+
androidApp/src/selfSignedRelease/assets/adi-registration.properties

composeApp/src/commonMain/kotlin/io/music_assistant/client/data/model/client/AppMediaItem.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ abstract class AppMediaItem(
5656

5757
val isInLibrary = provider == "library"
5858

59+
val isExplicit = metadata?.explicit == true
60+
5961
/**
6062
* URI suitable for the play_media API.
6163
* For genres, always constructs a full URI since the server requires it.

composeApp/src/commonMain/kotlin/io/music_assistant/client/ui/compose/common/items/MediaItems.kt

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import androidx.compose.foundation.shape.CircleShape
2525
import androidx.compose.foundation.shape.RoundedCornerShape
2626
import androidx.compose.material.icons.Icons
2727
import androidx.compose.material.icons.filled.Check
28+
import androidx.compose.material.icons.filled.Explicit
2829
import androidx.compose.material.icons.filled.Favorite
2930
import androidx.compose.material.icons.filled.Podcasts
3031
import androidx.compose.material.icons.filled.Schedule
@@ -43,6 +44,7 @@ import androidx.compose.ui.layout.ContentScale
4344
import androidx.compose.ui.platform.LocalDensity
4445
import androidx.compose.ui.text.style.TextAlign
4546
import androidx.compose.ui.text.style.TextOverflow
47+
import androidx.compose.ui.unit.Dp
4648
import androidx.compose.ui.unit.dp
4749
import coil3.compose.AsyncImage
4850
import io.music_assistant.client.data.model.client.AppMediaItem
@@ -56,8 +58,11 @@ import io.music_assistant.client.ui.compose.common.icons.TrackIcon
5658
import io.music_assistant.client.ui.compose.common.painters.rememberPlaceholderPainter
5759
import io.music_assistant.client.ui.compose.common.painters.rememberVinylRecordPainter
5860
import io.music_assistant.client.ui.compose.common.painters.rememberWaveformPainter
59-
import musicassistantclient.composeapp.generated.resources.*
6061
import musicassistantclient.composeapp.generated.resources.Res
62+
import musicassistantclient.composeapp.generated.resources.cd_favorite
63+
import musicassistantclient.composeapp.generated.resources.cd_fully_played
64+
import musicassistantclient.composeapp.generated.resources.cd_in_progress
65+
import musicassistantclient.composeapp.generated.resources.cd_vinyl_record
6166
import org.jetbrains.compose.resources.stringResource
6267

6368
/**
@@ -86,7 +91,6 @@ fun ArtistGridItem(
8691
Badges(
8792
item = item,
8893
providerIconFetcher = providerIconFetcher,
89-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
9094
)
9195
}
9296
Spacer(Modifier.height(4.dp))
@@ -166,7 +170,6 @@ fun AlbumGridItem(
166170
Badges(
167171
item = item,
168172
providerIconFetcher = providerIconFetcher,
169-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
170173
)
171174
}
172175
Spacer(Modifier.height(4.dp))
@@ -258,7 +261,6 @@ fun PlaylistGridItem(
258261
Badges(
259262
item = item,
260263
providerIconFetcher = providerIconFetcher,
261-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
262264
)
263265
}
264266
Spacer(Modifier.height(4.dp))
@@ -372,7 +374,6 @@ fun PodcastGridItem(
372374
Badges(
373375
item = item,
374376
providerIconFetcher = providerIconFetcher,
375-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
376377
)
377378
}
378379
Spacer(Modifier.height(4.dp))
@@ -484,7 +485,6 @@ internal fun TrackGridItem(
484485
Badges(
485486
item = item,
486487
providerIconFetcher = providerIconFetcher,
487-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
488488
)
489489
}
490490
GridPlayableItemLabels(item)
@@ -554,7 +554,6 @@ internal fun PodcastEpisodeGridItem(
554554
Badges(
555555
item = item,
556556
providerIconFetcher = providerIconFetcher,
557-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
558557
)
559558
ProgressBadge(
560559
fullyPlayed = item.fullyPlayed,
@@ -645,7 +644,6 @@ internal fun RadioGridItem(
645644
Badges(
646645
item = item,
647646
providerIconFetcher = providerIconFetcher,
648-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
649647
)
650648
}
651649
GridPlayableItemLabels(item)
@@ -709,7 +707,6 @@ internal fun AudiobookGridItem(
709707
Badges(
710708
item = item,
711709
providerIconFetcher = providerIconFetcher,
712-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
713710
)
714711
ProgressBadge(
715712
fullyPlayed = item.fullyPlayed,
@@ -793,8 +790,10 @@ private fun AudiobookImage(
793790
private fun GridPlayableItemLabels(item: PlayableItem) {
794791
Spacer(Modifier.height(4.dp))
795792
Text(
796-
text = "${item.name}${item.version
797-
?.trim()?.takeIf { it.isNotBlank() }?.let { " ($it)" } ?: ""}",
793+
text = "${item.name}${
794+
item.version
795+
?.trim()?.takeIf { it.isNotBlank() }?.let { " ($it)" } ?: ""
796+
}",
798797
style = MaterialTheme.typography.bodyMedium,
799798
maxLines = 1,
800799
overflow = TextOverflow.Ellipsis,
@@ -836,20 +835,35 @@ private fun GridItem(
836835
}
837836

838837
@Composable
839-
fun Badges(
838+
fun BoxScope.Badges(
840839
item: AppMediaItem,
841840
providerIconFetcher: (@Composable (Modifier, String) -> Unit)?,
842-
modifier: Modifier,
841+
badgeSize: Dp = 16.dp,
842+
badgePadding: Dp = 0.dp,
843843
) {
844+
val modifier = Modifier.padding(badgePadding).size(badgeSize)
845+
val bottomEnd = modifier.align(Alignment.BottomEnd)
844846
if (item.favorite == true) {
845847
Icon(
846-
modifier = modifier,
848+
modifier = bottomEnd,
847849
imageVector = Icons.Filled.Favorite,
848850
contentDescription = stringResource(Res.string.cd_favorite),
849851
tint = Color(0xFFEF7BC4),
850852
)
851853
} else {
852-
providerIconFetcher?.invoke(modifier.background(Color.Gray, CircleShape), item.provider)
854+
providerIconFetcher?.invoke(
855+
bottomEnd.background(Color.Gray, CircleShape),
856+
item.provider,
857+
)
858+
}
859+
if (item.isExplicit) {
860+
Icon(
861+
modifier = modifier.align(Alignment.TopEnd)
862+
.background(Color.White, RoundedCornerShape(2.dp)),
863+
imageVector = Icons.Filled.Explicit,
864+
contentDescription = stringResource(Res.string.cd_favorite),
865+
tint = Color.Black,
866+
)
853867
}
854868
}
855869

@@ -913,15 +927,16 @@ internal fun TrackRowItem(
913927
) {
914928
RowItem(
915929
modifier = modifier,
916-
name = "${item.name}${item.version
917-
?.trim()?.takeIf { it.isNotBlank() }?.let { " ($it)" } ?: ""}",
930+
name = "${item.name}${
931+
item.version
932+
?.trim()?.takeIf { it.isNotBlank() }?.let { " ($it)" } ?: ""
933+
}",
918934
subtitle = item.subtitle,
919935
imageContent = {
920936
TrackImage(item, serverUrl)
921937
Badges(
922938
item = item,
923939
providerIconFetcher = providerIconFetcher,
924-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
925940
)
926941
},
927942
onClick = { onClick(item) },
@@ -947,7 +962,6 @@ internal fun AlbumRowItem(
947962
Badges(
948963
item = item,
949964
providerIconFetcher = providerIconFetcher,
950-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
951965
)
952966
},
953967
onClick = { onClick(item) },
@@ -973,7 +987,6 @@ internal fun ArtistRowItem(
973987
Badges(
974988
item = item,
975989
providerIconFetcher = providerIconFetcher,
976-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
977990
)
978991
},
979992
onClick = { onClick(item) },
@@ -999,7 +1012,6 @@ internal fun PlaylistRowItem(
9991012
Badges(
10001013
item = item,
10011014
providerIconFetcher = providerIconFetcher,
1002-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
10031015
)
10041016
},
10051017
onClick = { onClick(item) },
@@ -1025,7 +1037,6 @@ internal fun PodcastRowItem(
10251037
Badges(
10261038
item = item,
10271039
providerIconFetcher = providerIconFetcher,
1028-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
10291040
)
10301041
},
10311042
onClick = { onClick(item) },
@@ -1051,7 +1062,6 @@ internal fun PodcastEpisodeRowItem(
10511062
Badges(
10521063
item = item,
10531064
providerIconFetcher = providerIconFetcher,
1054-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
10551065
)
10561066
ProgressBadge(
10571067
fullyPlayed = item.fullyPlayed,
@@ -1081,7 +1091,6 @@ internal fun RadioRowItem(
10811091
Badges(
10821092
item = item,
10831093
providerIconFetcher = providerIconFetcher,
1084-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
10851094
)
10861095
},
10871096
onClick = { onClick(item) },
@@ -1108,7 +1117,6 @@ fun GenreGridItem(
11081117
Badges(
11091118
item = item,
11101119
providerIconFetcher = providerIconFetcher,
1111-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
11121120
)
11131121
}
11141122
Spacer(Modifier.height(4.dp))
@@ -1180,7 +1188,6 @@ internal fun GenreRowItem(
11801188
Badges(
11811189
item = item,
11821190
providerIconFetcher = providerIconFetcher,
1183-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
11841191
)
11851192
},
11861193
onClick = { onClick(item) },
@@ -1206,7 +1213,6 @@ internal fun AudiobookRowItem(
12061213
Badges(
12071214
item = item,
12081215
providerIconFetcher = providerIconFetcher,
1209-
modifier = Modifier.align(Alignment.BottomEnd).size(16.dp),
12101216
)
12111217
ProgressBadge(
12121218
fullyPlayed = item.fullyPlayed,

composeApp/src/commonMain/kotlin/io/music_assistant/client/ui/compose/item/ItemHeader.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.aspectRatio
1111
import androidx.compose.foundation.layout.fillMaxSize
1212
import androidx.compose.foundation.layout.fillMaxWidth
1313
import androidx.compose.foundation.layout.padding
14-
import androidx.compose.foundation.layout.size
1514
import androidx.compose.foundation.layout.widthIn
1615
import androidx.compose.foundation.shape.CircleShape
1716
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -380,10 +379,8 @@ private fun Image(
380379
Badges(
381380
item,
382381
providerIconFetcher,
383-
modifier = Modifier
384-
.align(Alignment.BottomEnd)
385-
.padding(end = 8.dp, bottom = 8.dp)
386-
.size(24.dp),
382+
badgeSize = 24.dp,
383+
badgePadding = 8.dp,
387384
)
388385
}
389386
}

0 commit comments

Comments
 (0)