clear the build warnings and fail on new ones
A clean build now emits no warnings of its own, and Kotlin `allWarningsAsErrors` plus lint `warningsAsErrors` stop new ones from sneaking back in. - Kotlin: give SearchFilter's @StringRes parameter an explicit @param: target; use safe calls for File.parentFile in StringResourcesTest. - Packaging: keep debug symbols for the prebuilt .so files that have no symbol table, which is what the "unable to strip" warning was about. - Lint: move `modifier` to the first optional parameter across the Compose screens, use mutableIntStateOf for int state, read Resources via LocalResources, use the KTX Bitmap.get/String.toUri, drop the unused ic_action_name and ic_stat_name bitmaps and the dead -v24 qualifier on the notification vector, fix the pt-BR "album" accents and the unused Vietnamese/Thai plural quantities, and suppress the intentional cleartext/user-certificate, backup, exported-service and plural-candidate findings. Disable the version-update nags, which the dependency-update process owns. The AboutLibraries plugin still resolves the variant classpaths during configuration, so AGP keeps warning about that one; upstream in mikepenz/AboutLibraries#1369.
@@ -43,7 +43,28 @@ android {
|
|||||||
|
|
||||||
lint {
|
lint {
|
||||||
checkReleaseBuilds = false
|
checkReleaseBuilds = false
|
||||||
disable += setOf("MissingTranslation", "MissingQuantity")
|
warningsAsErrors = true
|
||||||
|
disable +=
|
||||||
|
setOf(
|
||||||
|
"MissingTranslation",
|
||||||
|
"MissingQuantity",
|
||||||
|
// Version nags are handled by the dependency-update process, not the build.
|
||||||
|
"AndroidGradlePluginVersion",
|
||||||
|
"GradleDependency",
|
||||||
|
"NewerVersionAvailable",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
packaging {
|
||||||
|
jniLibs {
|
||||||
|
// Prebuilt .so files with no symbol table; leaving them unstripped avoids the strip warning.
|
||||||
|
keepDebugSymbols +=
|
||||||
|
setOf(
|
||||||
|
"**/libandroidx.graphics.path.so",
|
||||||
|
"**/libdatastore_shared_counter.so",
|
||||||
|
"**/libsqliteJni.so",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testOptions {
|
testOptions {
|
||||||
@@ -71,6 +92,7 @@ android {
|
|||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_17)
|
||||||
|
allWarningsAsErrors.set(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +104,8 @@ ksp {
|
|||||||
arg("room.schemaLocation", "$projectDir/schemas")
|
arg("room.schemaLocation", "$projectDir/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolving the variant classpaths here makes AGP warn that a configuration was resolved during
|
||||||
|
// configuration time; upstream, tracked in mikepenz/AboutLibraries#1369.
|
||||||
aboutLibraries {
|
aboutLibraries {
|
||||||
collect {
|
collect {
|
||||||
configPath = file("config")
|
configPath = file("config")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||||
@@ -18,7 +19,8 @@
|
|||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Subtracks">
|
android:theme="@style/Theme.Subtracks"
|
||||||
|
tools:ignore="DataExtractionRules,UnusedAttribute">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
@@ -35,7 +37,8 @@
|
|||||||
<service
|
<service
|
||||||
android:name=".playback.PlaybackService"
|
android:name=".playback.PlaybackService"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:foregroundServiceType="mediaPlayback">
|
android:foregroundServiceType="mediaPlayback"
|
||||||
|
tools:ignore="ExportedService">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="androidx.media3.session.MediaSessionService" />
|
<action android:name="androidx.media3.session.MediaSessionService" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package com.subtracks.data.download
|
|||||||
|
|
||||||
import android.app.DownloadManager
|
import android.app.DownloadManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import androidx.core.net.toUri
|
||||||
import com.subtracks.data.model.DownloadError
|
import com.subtracks.data.model.DownloadError
|
||||||
|
|
||||||
class SystemDownloadEngine(
|
class SystemDownloadEngine(
|
||||||
@@ -12,7 +12,7 @@ class SystemDownloadEngine(
|
|||||||
override fun enqueue(request: EngineRequest): Long {
|
override fun enqueue(request: EngineRequest): Long {
|
||||||
val download =
|
val download =
|
||||||
DownloadManager
|
DownloadManager
|
||||||
.Request(Uri.parse(request.uri))
|
.Request(request.uri.toUri())
|
||||||
.setTitle(request.title)
|
.setTitle(request.title)
|
||||||
.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_MUSIC, request.path)
|
.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_MUSIC, request.path)
|
||||||
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)
|
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)
|
||||||
|
|||||||
@@ -248,11 +248,11 @@ fun HeroHeader(
|
|||||||
onDownloadAction: (BulkDownloadAction) -> Unit,
|
onDownloadAction: (BulkDownloadAction) -> Unit,
|
||||||
onMore: () -> Unit,
|
onMore: () -> Unit,
|
||||||
topInset: Dp,
|
topInset: Dp,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
controlsModifier: Modifier = Modifier,
|
controlsModifier: Modifier = Modifier,
|
||||||
thumbnailRef: CoverArtRef? = null,
|
thumbnailRef: CoverArtRef? = null,
|
||||||
comment: String? = null,
|
comment: String? = null,
|
||||||
onSubtitleClick: (() -> Unit)? = null,
|
onSubtitleClick: (() -> Unit)? = null,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier =
|
modifier =
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalResources
|
||||||
import androidx.compose.ui.res.pluralStringResource
|
import androidx.compose.ui.res.pluralStringResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
@@ -123,6 +123,7 @@ fun HomeListScreen(
|
|||||||
artists: LazyPagingItems<Artist>,
|
artists: LazyPagingItems<Artist>,
|
||||||
songs: LazyPagingItems<AlbumSongItem>,
|
songs: LazyPagingItems<AlbumSongItem>,
|
||||||
playlists: LazyPagingItems<Playlist>,
|
playlists: LazyPagingItems<Playlist>,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
genres: List<String> = emptyList(),
|
genres: List<String> = emptyList(),
|
||||||
decades: List<Long> = emptyList(),
|
decades: List<Long> = emptyList(),
|
||||||
coverArt: (String?, Boolean) -> CoverArtRef? = { _, _ -> null },
|
coverArt: (String?, Boolean) -> CoverArtRef? = { _, _ -> null },
|
||||||
@@ -135,10 +136,9 @@ fun HomeListScreen(
|
|||||||
onLongClick: (MenuTarget) -> Unit = {},
|
onLongClick: (MenuTarget) -> Unit = {},
|
||||||
onGenreClick: (String) -> Unit = {},
|
onGenreClick: (String) -> Unit = {},
|
||||||
onDecadeClick: (Long) -> Unit = {},
|
onDecadeClick: (Long) -> Unit = {},
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val now = remember { System.currentTimeMillis() }
|
val now = remember { System.currentTimeMillis() }
|
||||||
val resources = LocalContext.current.resources
|
val resources = LocalResources.current
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ fun HomeScreen(
|
|||||||
feed: HomeFeed,
|
feed: HomeFeed,
|
||||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||||
playingSongId: String?,
|
playingSongId: String?,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
topInset: Dp = 0.dp,
|
topInset: Dp = 0.dp,
|
||||||
bottomInset: Dp = 0.dp,
|
bottomInset: Dp = 0.dp,
|
||||||
onAlbumClick: (Album) -> Unit = {},
|
onAlbumClick: (Album) -> Unit = {},
|
||||||
@@ -182,7 +183,6 @@ fun HomeScreen(
|
|||||||
onGenreClick: (String) -> Unit = {},
|
onGenreClick: (String) -> Unit = {},
|
||||||
onDecadeClick: (Long) -> Unit = {},
|
onDecadeClick: (Long) -> Unit = {},
|
||||||
onSync: () -> Unit = {},
|
onSync: () -> Unit = {},
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||||
if (feed.loading) {
|
if (feed.loading) {
|
||||||
@@ -295,6 +295,7 @@ fun OfflineHomeScreen(
|
|||||||
songs: List<AlbumSongItem>,
|
songs: List<AlbumSongItem>,
|
||||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||||
playingSongId: String?,
|
playingSongId: String?,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
topInset: Dp = 0.dp,
|
topInset: Dp = 0.dp,
|
||||||
bottomInset: Dp = 0.dp,
|
bottomInset: Dp = 0.dp,
|
||||||
onAlbumClick: (Album) -> Unit = {},
|
onAlbumClick: (Album) -> Unit = {},
|
||||||
@@ -303,7 +304,6 @@ fun OfflineHomeScreen(
|
|||||||
onSongPlay: (Song) -> Unit = {},
|
onSongPlay: (Song) -> Unit = {},
|
||||||
onLongClick: (MenuTarget) -> Unit = {},
|
onLongClick: (MenuTarget) -> Unit = {},
|
||||||
onMore: (OfflineListKind) -> Unit = {},
|
onMore: (OfflineListKind) -> Unit = {},
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ fun AlbumDetailRoute(
|
|||||||
fun AlbumDetailScreen(
|
fun AlbumDetailScreen(
|
||||||
album: Album?,
|
album: Album?,
|
||||||
songs: List<Song>,
|
songs: List<Song>,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
discs: List<Disc> = emptyList(),
|
discs: List<Disc> = emptyList(),
|
||||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||||
artwork: ArtworkColors?,
|
artwork: ArtworkColors?,
|
||||||
@@ -160,7 +161,6 @@ fun AlbumDetailScreen(
|
|||||||
onMore: () -> Unit = {},
|
onMore: () -> Unit = {},
|
||||||
onArtistClick: (() -> Unit)? = null,
|
onArtistClick: (() -> Unit)? = null,
|
||||||
playingSongId: String? = null,
|
playingSongId: String? = null,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val multiDisc = songs.map { it.disc ?: 1L }.distinct().size > 1
|
val multiDisc = songs.map { it.disc ?: 1L }.distinct().size > 1
|
||||||
val resources = LocalResources.current
|
val resources = LocalResources.current
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ fun AlbumsContent(
|
|||||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||||
bottomInset: Dp,
|
bottomInset: Dp,
|
||||||
onAlbumClick: (Album) -> Unit,
|
onAlbumClick: (Album) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
onLongClick: (MenuTarget) -> Unit = {},
|
onLongClick: (MenuTarget) -> Unit = {},
|
||||||
filtered: Boolean = false,
|
filtered: Boolean = false,
|
||||||
onClearFilters: () -> Unit = {},
|
onClearFilters: () -> Unit = {},
|
||||||
@@ -55,7 +56,6 @@ fun AlbumsContent(
|
|||||||
topInset: Dp = 0.dp,
|
topInset: Dp = 0.dp,
|
||||||
onSync: () -> Unit = {},
|
onSync: () -> Unit = {},
|
||||||
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ fun ArtistDetailRoute(
|
|||||||
@Composable
|
@Composable
|
||||||
fun ArtistDetailScreen(
|
fun ArtistDetailScreen(
|
||||||
artist: Artist?,
|
artist: Artist?,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
artistName: String = "",
|
artistName: String = "",
|
||||||
isAlbumArtist: Boolean = false,
|
isAlbumArtist: Boolean = false,
|
||||||
albums: List<Album>,
|
albums: List<Album>,
|
||||||
@@ -232,7 +233,6 @@ fun ArtistDetailScreen(
|
|||||||
starred: Boolean = false,
|
starred: Boolean = false,
|
||||||
onToggleStar: (() -> Unit)? = null,
|
onToggleStar: (() -> Unit)? = null,
|
||||||
onShuffle: () -> Unit = {},
|
onShuffle: () -> Unit = {},
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val listState = rememberLazyGridState()
|
val listState = rememberLazyGridState()
|
||||||
val fill = rememberViewportFill(listState)
|
val fill = rememberViewportFill(listState)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ fun ArtistsContent(
|
|||||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||||
bottomInset: Dp,
|
bottomInset: Dp,
|
||||||
onArtistClick: (Artist) -> Unit,
|
onArtistClick: (Artist) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
onLongClick: (MenuTarget) -> Unit = {},
|
onLongClick: (MenuTarget) -> Unit = {},
|
||||||
filtered: Boolean = false,
|
filtered: Boolean = false,
|
||||||
onClearFilters: () -> Unit = {},
|
onClearFilters: () -> Unit = {},
|
||||||
@@ -52,7 +53,6 @@ fun ArtistsContent(
|
|||||||
topInset: Dp = 0.dp,
|
topInset: Dp = 0.dp,
|
||||||
onSync: () -> Unit = {},
|
onSync: () -> Unit = {},
|
||||||
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ fun LibraryScreen(
|
|||||||
onPlaylistClick: (Playlist) -> Unit,
|
onPlaylistClick: (Playlist) -> Unit,
|
||||||
onSync: () -> Unit,
|
onSync: () -> Unit,
|
||||||
onOpenSettings: () -> Unit,
|
onOpenSettings: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
onOpenSearch: () -> Unit = {},
|
onOpenSearch: () -> Unit = {},
|
||||||
offline: Boolean = false,
|
offline: Boolean = false,
|
||||||
onExitOffline: () -> Unit = {},
|
onExitOffline: () -> Unit = {},
|
||||||
@@ -409,7 +410,6 @@ fun LibraryScreen(
|
|||||||
playlistDownloads: Map<String, ListDownloadStatus> = emptyMap(),
|
playlistDownloads: Map<String, ListDownloadStatus> = emptyMap(),
|
||||||
dismissals: Flow<Unit> = emptyFlow(),
|
dismissals: Flow<Unit> = emptyFlow(),
|
||||||
homeContent: @Composable (topInset: Dp, bottomInset: Dp) -> Unit = { _, _ -> },
|
homeContent: @Composable (topInset: Dp, bottomInset: Dp) -> Unit = { _, _ -> },
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val pagerState =
|
val pagerState =
|
||||||
rememberPagerState(
|
rememberPagerState(
|
||||||
@@ -831,6 +831,7 @@ private fun ListOptionsGlyph(modifier: Modifier = Modifier) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("FrequentlyChangingValue")
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun LibraryTabs(
|
internal fun LibraryTabs(
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ fun PlaylistDetailScreen(
|
|||||||
songs: LazyPagingItems<PlaylistSongItem>,
|
songs: LazyPagingItems<PlaylistSongItem>,
|
||||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||||
artwork: ArtworkColors?,
|
artwork: ArtworkColors?,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
downloads: Map<String, SongDownload> = emptyMap(),
|
downloads: Map<String, SongDownload> = emptyMap(),
|
||||||
downloadStatus: ListDownloadStatus = ListDownloadStatus(),
|
downloadStatus: ListDownloadStatus = ListDownloadStatus(),
|
||||||
offline: Boolean = false,
|
offline: Boolean = false,
|
||||||
@@ -131,7 +132,6 @@ fun PlaylistDetailScreen(
|
|||||||
onPlay: () -> Unit = {},
|
onPlay: () -> Unit = {},
|
||||||
onMore: () -> Unit = {},
|
onMore: () -> Unit = {},
|
||||||
playingSongId: String? = null,
|
playingSongId: String? = null,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
HeroDetailScaffold(
|
HeroDetailScaffold(
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ fun PlaylistsContent(
|
|||||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||||
bottomInset: Dp,
|
bottomInset: Dp,
|
||||||
onPlaylistClick: (Playlist) -> Unit,
|
onPlaylistClick: (Playlist) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
onLongClick: (MenuTarget) -> Unit = {},
|
onLongClick: (MenuTarget) -> Unit = {},
|
||||||
filtered: Boolean = false,
|
filtered: Boolean = false,
|
||||||
onClearFilters: () -> Unit = {},
|
onClearFilters: () -> Unit = {},
|
||||||
@@ -51,7 +52,6 @@ fun PlaylistsContent(
|
|||||||
topInset: Dp = 0.dp,
|
topInset: Dp = 0.dp,
|
||||||
onSync: () -> Unit = {},
|
onSync: () -> Unit = {},
|
||||||
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ private fun buildVectorPath(vector: ImageVector): Path {
|
|||||||
@Composable
|
@Composable
|
||||||
fun SongRow(
|
fun SongRow(
|
||||||
song: Song,
|
song: Song,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
coverArtId: String? = null,
|
coverArtId: String? = null,
|
||||||
coverArt: ((String?, Boolean) -> CoverArtRef?)? = null,
|
coverArt: ((String?, Boolean) -> CoverArtRef?)? = null,
|
||||||
isPlaying: Boolean = false,
|
isPlaying: Boolean = false,
|
||||||
@@ -100,7 +101,6 @@ fun SongRow(
|
|||||||
durationSeconds: Long? = null,
|
durationSeconds: Long? = null,
|
||||||
download: SongDownload? = null,
|
download: SongDownload? = null,
|
||||||
trailingContent: (@Composable () -> Unit)? = null,
|
trailingContent: (@Composable () -> Unit)? = null,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ fun MiniPlayer(
|
|||||||
onExpand: () -> Unit,
|
onExpand: () -> Unit,
|
||||||
onPlayPause: () -> Unit,
|
onPlayPause: () -> Unit,
|
||||||
onNext: () -> Unit,
|
onNext: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
progressInset: Boolean = false,
|
progressInset: Boolean = false,
|
||||||
onExpandDrag: (Float) -> Unit = {},
|
onExpandDrag: (Float) -> Unit = {},
|
||||||
onExpandRelease: (Float) -> Unit = {},
|
onExpandRelease: (Float) -> Unit = {},
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val item = state.item ?: return
|
val item = state.item ?: return
|
||||||
var dragUpPx by remember { mutableFloatStateOf(0f) }
|
var dragUpPx by remember { mutableFloatStateOf(0f) }
|
||||||
|
|||||||
@@ -182,9 +182,9 @@ fun NowPlayingRoute(
|
|||||||
onQueue: () -> Unit,
|
onQueue: () -> Unit,
|
||||||
onViewAlbum: (String) -> Unit,
|
onViewAlbum: (String) -> Unit,
|
||||||
onViewArtist: (String) -> Unit,
|
onViewArtist: (String) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
contextMenuHost: ContextMenuHost? = null,
|
contextMenuHost: ContextMenuHost? = null,
|
||||||
setStar: (StarType, String, Boolean) -> Unit,
|
setStar: (StarType, String, Boolean) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
controller: PlaybackController = koinInject(),
|
controller: PlaybackController = koinInject(),
|
||||||
libraryRepository: LibraryRepository = koinInject(),
|
libraryRepository: LibraryRepository = koinInject(),
|
||||||
downloadRepository: DownloadRepository = koinInject(),
|
downloadRepository: DownloadRepository = koinInject(),
|
||||||
@@ -286,6 +286,7 @@ fun NowPlayingScreen(
|
|||||||
onPlayPause: () -> Unit,
|
onPlayPause: () -> Unit,
|
||||||
onNext: () -> Unit,
|
onNext: () -> Unit,
|
||||||
onPrevious: () -> Unit,
|
onPrevious: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
onSkipPrevious: () -> Unit = onPrevious,
|
onSkipPrevious: () -> Unit = onPrevious,
|
||||||
onShuffle: () -> Unit = {},
|
onShuffle: () -> Unit = {},
|
||||||
onRepeat: () -> Unit = {},
|
onRepeat: () -> Unit = {},
|
||||||
@@ -298,7 +299,6 @@ fun NowPlayingScreen(
|
|||||||
thumbnailRef: CoverArtRef? = null,
|
thumbnailRef: CoverArtRef? = null,
|
||||||
previousArt: NowPlayingArt? = null,
|
previousArt: NowPlayingArt? = null,
|
||||||
nextArt: NowPlayingArt? = null,
|
nextArt: NowPlayingArt? = null,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val playButtonSize = 90.dp
|
val playButtonSize = 90.dp
|
||||||
val playCircleDiameter = playButtonSize * 20f / 24f
|
val playCircleDiameter = playButtonSize * 20f / 24f
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import androidx.compose.material3.TopAppBar
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -106,10 +107,10 @@ class QueueViewModel(
|
|||||||
var ready by mutableStateOf(false)
|
var ready by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var initialIndex by mutableStateOf(0)
|
var initialIndex by mutableIntStateOf(0)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var generation by mutableStateOf(0)
|
var generation by mutableIntStateOf(0)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private var nextId = 0L
|
private var nextId = 0L
|
||||||
@@ -562,6 +563,7 @@ internal fun dropTarget(
|
|||||||
return (before - if (before > from) 1 else 0) + 1
|
return (before - if (before > from) 1 else 0) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("ModifierParameter")
|
||||||
@Composable
|
@Composable
|
||||||
private fun QueueRowItem(
|
private fun QueueRowItem(
|
||||||
row: QueueRow,
|
row: QueueRow,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ import org.koin.compose.koinInject
|
|||||||
import org.koin.compose.viewmodel.koinViewModel
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
||||||
enum class SearchFilter(
|
enum class SearchFilter(
|
||||||
@StringRes val label: Int,
|
@param:StringRes val label: Int,
|
||||||
) {
|
) {
|
||||||
Songs(R.string.search_songs),
|
Songs(R.string.search_songs),
|
||||||
Albums(R.string.resources_album_name),
|
Albums(R.string.resources_album_name),
|
||||||
@@ -125,6 +125,7 @@ fun SearchScreen(
|
|||||||
query: String,
|
query: String,
|
||||||
onQueryChange: (String) -> Unit,
|
onQueryChange: (String) -> Unit,
|
||||||
results: SearchResults,
|
results: SearchResults,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
filters: Set<SearchFilter> = ALL_FILTERS,
|
filters: Set<SearchFilter> = ALL_FILTERS,
|
||||||
onToggleFilter: (SearchFilter) -> Unit = {},
|
onToggleFilter: (SearchFilter) -> Unit = {},
|
||||||
coverArt: (String?, Boolean) -> CoverArtRef? = { _, _ -> null },
|
coverArt: (String?, Boolean) -> CoverArtRef? = { _, _ -> null },
|
||||||
@@ -135,7 +136,6 @@ fun SearchScreen(
|
|||||||
onPlaylistClick: (Playlist) -> Unit = {},
|
onPlaylistClick: (Playlist) -> Unit = {},
|
||||||
onSongClick: (Song) -> Unit = {},
|
onSongClick: (Song) -> Unit = {},
|
||||||
onLongClick: (MenuTarget) -> Unit = {},
|
onLongClick: (MenuTarget) -> Unit = {},
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
val backLabel = stringResource(R.string.navigation_back)
|
val backLabel = stringResource(R.string.navigation_back)
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ fun AddSourceScreen(
|
|||||||
onSave: () -> Unit,
|
onSave: () -> Unit,
|
||||||
onDelete: () -> Unit,
|
onDelete: () -> Unit,
|
||||||
onBack: (() -> Unit)?,
|
onBack: (() -> Unit)?,
|
||||||
dismissals: Flow<Unit> = emptyFlow(),
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
dismissals: Flow<Unit> = emptyFlow(),
|
||||||
) {
|
) {
|
||||||
val nameFocus = remember { FocusRequester() }
|
val nameFocus = remember { FocusRequester() }
|
||||||
val addressFocus = remember { FocusRequester() }
|
val addressFocus = remember { FocusRequester() }
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import androidx.compose.material3.TextButton
|
|||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
@@ -124,6 +125,7 @@ fun SettingsScreen(
|
|||||||
downloadQuality: StreamQuality,
|
downloadQuality: StreamQuality,
|
||||||
downloadOverMetered: Boolean,
|
downloadOverMetered: Boolean,
|
||||||
scrobbling: Boolean,
|
scrobbling: Boolean,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
offline: Boolean = false,
|
offline: Boolean = false,
|
||||||
onSelectSource: (Long) -> Unit,
|
onSelectSource: (Long) -> Unit,
|
||||||
onEditServer: (Long) -> Unit,
|
onEditServer: (Long) -> Unit,
|
||||||
@@ -139,7 +141,6 @@ fun SettingsScreen(
|
|||||||
onOpenLicenses: () -> Unit,
|
onOpenLicenses: () -> Unit,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
dismissals: Flow<Unit> = emptyFlow(),
|
dismissals: Flow<Unit> = emptyFlow(),
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
var dialog by remember { mutableStateOf<SettingsDialog?>(null) }
|
var dialog by remember { mutableStateOf<SettingsDialog?>(null) }
|
||||||
DismissOnRequest(dismissals) { dialog = null }
|
DismissOnRequest(dismissals) { dialog = null }
|
||||||
@@ -397,7 +398,7 @@ private fun ConcurrencyDialog(
|
|||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val resources = LocalResources.current
|
val resources = LocalResources.current
|
||||||
var draft by remember(selected) { mutableStateOf(selected) }
|
var draft by remember(selected) { mutableIntStateOf(selected) }
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismiss,
|
onDismissRequest = onDismiss,
|
||||||
title = { Text(stringResource(R.string.sync_concurrency)) },
|
title = { Text(stringResource(R.string.sync_concurrency)) },
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.luminance
|
import androidx.compose.ui.graphics.luminance
|
||||||
|
import androidx.core.graphics.get
|
||||||
import androidx.palette.graphics.Palette
|
import androidx.palette.graphics.Palette
|
||||||
import coil3.SingletonImageLoader
|
import coil3.SingletonImageLoader
|
||||||
import coil3.compose.LocalPlatformContext
|
import coil3.compose.LocalPlatformContext
|
||||||
@@ -202,7 +203,7 @@ object ArtworkSeedCache {
|
|||||||
x: Int,
|
x: Int,
|
||||||
y: Int,
|
y: Int,
|
||||||
): Float {
|
): Float {
|
||||||
val color = Color(bitmap.getPixel(x, y))
|
val color = Color(bitmap[x, y])
|
||||||
return 0.2126f * color.red + 0.7152f * color.green + 0.0722f * color.blue
|
return 0.2126f * color.red + 0.7152f * color.green + 0.0722f * color.blue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 441 B |
|
Before Width: | Height: | Size: 401 B |
|
Before Width: | Height: | Size: 318 B |
|
Before Width: | Height: | Size: 284 B |
|
Before Width: | Height: | Size: 600 B |
|
Before Width: | Height: | Size: 575 B |
|
Before Width: | Height: | Size: 925 B |
|
Before Width: | Height: | Size: 921 B |
@@ -1,8 +1,10 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="300"
|
android:viewportWidth="300"
|
||||||
android:viewportHeight="300">
|
android:viewportHeight="300"
|
||||||
|
tools:ignore="UnusedResources">
|
||||||
<group android:translateY="40.25">
|
<group android:translateY="40.25">
|
||||||
<path
|
<path
|
||||||
android:pathData="m23.84,-0c-12.76,0 -23.44,13 -23.65,25.12 -0.42,79.03 0,160.73 0,170.4 0,12.59 9.8,23.99 23.41,23.99l253.58,0c11.4,0 22.66,-12.38 22.66,-22.79L299.84,24.12c0,-10.8 -10.24,-23.81 -21.84,-23.81 -11.6,0 -254.16,-0.31 -254.16,-0.31zM39.05,25.28c0,0 217.71,0.71 223.67,0.71 6.07,0 12.17,6.83 12.17,12.06l0,142.25c0,8.97 -6.97,14.63 -12.48,14.64l-33.42,0.07c-5.32,0.01 -9.93,-7.19 -11.35,-10.61 -1.89,-4.55 -11.08,-25.75 -12.1,-28.1 -0.6,-1.38 -2.9,-2.83 -5.89,-2.83L98.33,153.45c-2.68,0 -4.89,2.87 -5.67,4.71 -1.12,2.66 -9.02,21.39 -11.63,27.57 -2.73,6.46 -4.37,9.06 -11.47,9.06l-30.97,0c-7.44,0 -13.69,-7.17 -13.67,-15.18l0.28,-139.51c0,-6.88 5.54,-14.83 13.85,-14.83z"
|
android:pathData="m23.84,-0c-12.76,0 -23.44,13 -23.65,25.12 -0.42,79.03 0,160.73 0,170.4 0,12.59 9.8,23.99 23.41,23.99l253.58,0c11.4,0 22.66,-12.38 22.66,-22.79L299.84,24.12c0,-10.8 -10.24,-23.81 -21.84,-23.81 -11.6,0 -254.16,-0.31 -254.16,-0.31zM39.05,25.28c0,0 217.71,0.71 223.67,0.71 6.07,0 12.17,6.83 12.17,12.06l0,142.25c0,8.97 -6.97,14.63 -12.48,14.64l-33.42,0.07c-5.32,0.01 -9.93,-7.19 -11.35,-10.61 -1.89,-4.55 -11.08,-25.75 -12.1,-28.1 -0.6,-1.38 -2.9,-2.83 -5.89,-2.83L98.33,153.45c-2.68,0 -4.89,2.87 -5.67,4.71 -1.12,2.66 -9.02,21.39 -11.63,27.57 -2.73,6.46 -4.37,9.06 -11.47,9.06l-30.97,0c-7.44,0 -13.69,-7.17 -13.67,-15.18l0.28,-139.51c0,-6.88 5.54,-14.83 13.85,-14.83z"
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
<string name="navigation_tabs_library">Biblioteca</string>
|
<string name="navigation_tabs_library">Biblioteca</string>
|
||||||
<string name="navigation_tabs_settings">Configurações</string>
|
<string name="navigation_tabs_settings">Configurações</string>
|
||||||
<plurals name="resources_album_count">
|
<plurals name="resources_album_count">
|
||||||
<item quantity="one">%1$d album</item>
|
<item quantity="one">%1$d álbum</item>
|
||||||
<item quantity="other">%1$d albums</item>
|
<item quantity="other">%1$d álbuns</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="resources_filter_album">Álbum</string>
|
<string name="resources_filter_album">Álbum</string>
|
||||||
<string name="resources_filter_artist">Artista</string>
|
<string name="resources_filter_artist">Artista</string>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<string name="settings_servers_fields_password">Senha</string>
|
<string name="settings_servers_fields_password">Senha</string>
|
||||||
<string name="settings_servers_fields_username">Usuário</string>
|
<string name="settings_servers_fields_username">Usuário</string>
|
||||||
<string name="navigation_tabs_home">Home</string>
|
<string name="navigation_tabs_home">Home</string>
|
||||||
<string name="resources_album_name">Albums</string>
|
<string name="resources_album_name">Álbuns</string>
|
||||||
<string name="resources_artist_name">Artists</string>
|
<string name="resources_artist_name">Artists</string>
|
||||||
<string name="resources_playlist_name">Playlists</string>
|
<string name="resources_playlist_name">Playlists</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
<string name="resources_filter_genre">ประเภท</string>
|
<string name="resources_filter_genre">ประเภท</string>
|
||||||
<string name="resources_filter_starred">ให้ดาว</string>
|
<string name="resources_filter_starred">ให้ดาว</string>
|
||||||
<plurals name="resources_song_count">
|
<plurals name="resources_song_count">
|
||||||
<item quantity="one">%1$d เพลง</item>
|
|
||||||
<item quantity="other">%1$d เพลง</item>
|
<item quantity="other">%1$d เพลง</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="resources_sort_by_artist">ศิลปิน</string>
|
<string name="resources_sort_by_artist">ศิลปิน</string>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
<string name="navigation_tabs_library">Thư viện</string>
|
<string name="navigation_tabs_library">Thư viện</string>
|
||||||
<string name="navigation_tabs_settings">Cài đặt</string>
|
<string name="navigation_tabs_settings">Cài đặt</string>
|
||||||
<plurals name="resources_album_count">
|
<plurals name="resources_album_count">
|
||||||
<item quantity="one">%1$d album</item>
|
|
||||||
<item quantity="other">%1$d album</item>
|
<item quantity="other">%1$d album</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="resources_filter_album">Theo album</string>
|
<string name="resources_filter_album">Theo album</string>
|
||||||
@@ -18,7 +17,6 @@
|
|||||||
<string name="resources_filter_genre">Theo thể loại</string>
|
<string name="resources_filter_genre">Theo thể loại</string>
|
||||||
<string name="resources_filter_starred">Theo yêu thích</string>
|
<string name="resources_filter_starred">Theo yêu thích</string>
|
||||||
<plurals name="resources_song_count">
|
<plurals name="resources_song_count">
|
||||||
<item quantity="one">%1$d bài hát</item>
|
|
||||||
<item quantity="other">%1$d bài hát</item>
|
<item quantity="other">%1$d bài hát</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="resources_sort_by_artist">Nghệ sĩ</string>
|
<string name="resources_sort_by_artist">Nghệ sĩ</string>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<string name="app_name">subtracks</string>
|
<string name="app_name">subtracks</string>
|
||||||
<string name="download_channel_description">Progress while songs download</string>
|
<string name="download_channel_description">Progress while songs download</string>
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
<string name="search">Search</string>
|
<string name="search">Search</string>
|
||||||
<string name="search_this_list">Search this list</string>
|
<string name="search_this_list">Search this list</string>
|
||||||
<string name="search_songs">Songs</string>
|
<string name="search_songs">Songs</string>
|
||||||
<string name="search_min_length">Type at least %1$d characters to search.</string>
|
<string name="search_min_length" tools:ignore="PluralsCandidate">Type at least %1$d characters to search.</string>
|
||||||
<string name="search_no_results">No results for “%1$s”.</string>
|
<string name="search_no_results">No results for “%1$s”.</string>
|
||||||
<string name="sort_by">Sort by</string>
|
<string name="sort_by">Sort by</string>
|
||||||
<string name="sort_ascending">Sort ascending</string>
|
<string name="sort_ascending">Sort ascending</string>
|
||||||
@@ -245,7 +245,7 @@
|
|||||||
<string name="error_server_unknown">Unknown error</string>
|
<string name="error_server_unknown">Unknown error</string>
|
||||||
<string name="error_server_malformed">Malformed response from the server</string>
|
<string name="error_server_malformed">Malformed response from the server</string>
|
||||||
<string name="error_server_truncated">Truncated response from the server</string>
|
<string name="error_server_truncated">Truncated response from the server</string>
|
||||||
<string name="error_library_too_large">Library is too large to sync: it exceeds %1$d rows</string>
|
<string name="error_library_too_large" tools:ignore="PluralsCandidate">Library is too large to sync: it exceeds %1$d rows</string>
|
||||||
<string name="error_http">HTTP %1$d</string>
|
<string name="error_http">HTTP %1$d</string>
|
||||||
|
|
||||||
<string name="home_section_recently_played_artists">Recently played artists</string>
|
<string name="home_section_recently_played_artists">Recently played artists</string>
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<network-security-config>
|
<network-security-config xmlns:tools="http://schemas.android.com/tools">
|
||||||
<base-config cleartextTrafficPermitted="true">
|
<base-config
|
||||||
|
cleartextTrafficPermitted="true"
|
||||||
|
tools:ignore="InsecureBaseConfiguration">
|
||||||
<trust-anchors>
|
<trust-anchors>
|
||||||
<certificates src="system" />
|
<certificates src="system" />
|
||||||
<certificates src="user" />
|
<certificates
|
||||||
|
src="user"
|
||||||
|
tools:ignore="AcceptsUserCertificates" />
|
||||||
</trust-anchors>
|
</trust-anchors>
|
||||||
</base-config>
|
</base-config>
|
||||||
</network-security-config>
|
</network-security-config>
|
||||||
|
|||||||
@@ -34,17 +34,17 @@ class StringResourcesTest {
|
|||||||
val locale = parse(file)
|
val locale = parse(file)
|
||||||
locale.forEach { (name, resource) ->
|
locale.forEach { (name, resource) ->
|
||||||
val base = default[name]
|
val base = default[name]
|
||||||
assertTrue("$name in ${file.parentFile.name} is missing from values/strings.xml", base != null)
|
assertTrue("$name in ${file.parentFile?.name} is missing from values/strings.xml", base != null)
|
||||||
assertEquals("$name kind differs in ${file.parentFile.name}", base!!.kind, resource.kind)
|
assertEquals("$name kind differs in ${file.parentFile?.name}", base!!.kind, resource.kind)
|
||||||
if (resource.kind == "plurals") {
|
if (resource.kind == "plurals") {
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"$name has an invalid quantity in ${file.parentFile.name}",
|
"$name has an invalid quantity in ${file.parentFile?.name}",
|
||||||
resource.quantities.all { it in validQuantities },
|
resource.quantities.all { it in validQuantities },
|
||||||
)
|
)
|
||||||
assertTrue("$name in ${file.parentFile.name} is missing the required 'other' quantity", "other" in resource.quantities)
|
assertTrue("$name in ${file.parentFile?.name} is missing the required 'other' quantity", "other" in resource.quantities)
|
||||||
}
|
}
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"$name placeholders differ in ${file.parentFile.name}",
|
"$name placeholders differ in ${file.parentFile?.name}",
|
||||||
placeholders(base.text),
|
placeholders(base.text),
|
||||||
placeholders(resource.text),
|
placeholders(resource.text),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -275,8 +275,8 @@ class DemoScreenshotTest {
|
|||||||
private fun DemoData.MiniPlayerOverlay(
|
private fun DemoData.MiniPlayerOverlay(
|
||||||
song: Song,
|
song: Song,
|
||||||
album: Album,
|
album: Album,
|
||||||
progressInset: Boolean = false,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
progressInset: Boolean = false,
|
||||||
) {
|
) {
|
||||||
MiniPlayer(
|
MiniPlayer(
|
||||||
state = playbackFor(song, album),
|
state = playbackFor(song, album),
|
||||||
|
|||||||