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 {
|
||||
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 {
|
||||
@@ -71,6 +92,7 @@ android {
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
allWarningsAsErrors.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +104,8 @@ ksp {
|
||||
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 {
|
||||
collect {
|
||||
configPath = file("config")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?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.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
@@ -18,7 +19,8 @@
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Subtracks">
|
||||
android:theme="@style/Theme.Subtracks"
|
||||
tools:ignore="DataExtractionRules,UnusedAttribute">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
@@ -35,7 +37,8 @@
|
||||
<service
|
||||
android:name=".playback.PlaybackService"
|
||||
android:exported="true"
|
||||
android:foregroundServiceType="mediaPlayback">
|
||||
android:foregroundServiceType="mediaPlayback"
|
||||
tools:ignore="ExportedService">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.media3.session.MediaSessionService" />
|
||||
</intent-filter>
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.subtracks.data.download
|
||||
|
||||
import android.app.DownloadManager
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import androidx.core.net.toUri
|
||||
import com.subtracks.data.model.DownloadError
|
||||
|
||||
class SystemDownloadEngine(
|
||||
@@ -12,7 +12,7 @@ class SystemDownloadEngine(
|
||||
override fun enqueue(request: EngineRequest): Long {
|
||||
val download =
|
||||
DownloadManager
|
||||
.Request(Uri.parse(request.uri))
|
||||
.Request(request.uri.toUri())
|
||||
.setTitle(request.title)
|
||||
.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_MUSIC, request.path)
|
||||
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)
|
||||
|
||||
@@ -248,11 +248,11 @@ fun HeroHeader(
|
||||
onDownloadAction: (BulkDownloadAction) -> Unit,
|
||||
onMore: () -> Unit,
|
||||
topInset: Dp,
|
||||
modifier: Modifier = Modifier,
|
||||
controlsModifier: Modifier = Modifier,
|
||||
thumbnailRef: CoverArtRef? = null,
|
||||
comment: String? = null,
|
||||
onSubtitleClick: (() -> Unit)? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier =
|
||||
|
||||
@@ -35,7 +35,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
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.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -123,6 +123,7 @@ fun HomeListScreen(
|
||||
artists: LazyPagingItems<Artist>,
|
||||
songs: LazyPagingItems<AlbumSongItem>,
|
||||
playlists: LazyPagingItems<Playlist>,
|
||||
modifier: Modifier = Modifier,
|
||||
genres: List<String> = emptyList(),
|
||||
decades: List<Long> = emptyList(),
|
||||
coverArt: (String?, Boolean) -> CoverArtRef? = { _, _ -> null },
|
||||
@@ -135,10 +136,9 @@ fun HomeListScreen(
|
||||
onLongClick: (MenuTarget) -> Unit = {},
|
||||
onGenreClick: (String) -> Unit = {},
|
||||
onDecadeClick: (Long) -> Unit = {},
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val now = remember { System.currentTimeMillis() }
|
||||
val resources = LocalContext.current.resources
|
||||
val resources = LocalResources.current
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
|
||||
@@ -172,6 +172,7 @@ fun HomeScreen(
|
||||
feed: HomeFeed,
|
||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||
playingSongId: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
topInset: Dp = 0.dp,
|
||||
bottomInset: Dp = 0.dp,
|
||||
onAlbumClick: (Album) -> Unit = {},
|
||||
@@ -182,7 +183,6 @@ fun HomeScreen(
|
||||
onGenreClick: (String) -> Unit = {},
|
||||
onDecadeClick: (Long) -> Unit = {},
|
||||
onSync: () -> Unit = {},
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||
if (feed.loading) {
|
||||
@@ -295,6 +295,7 @@ fun OfflineHomeScreen(
|
||||
songs: List<AlbumSongItem>,
|
||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||
playingSongId: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
topInset: Dp = 0.dp,
|
||||
bottomInset: Dp = 0.dp,
|
||||
onAlbumClick: (Album) -> Unit = {},
|
||||
@@ -303,7 +304,6 @@ fun OfflineHomeScreen(
|
||||
onSongPlay: (Song) -> Unit = {},
|
||||
onLongClick: (MenuTarget) -> Unit = {},
|
||||
onMore: (OfflineListKind) -> Unit = {},
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||
LazyColumn(
|
||||
|
||||
@@ -146,6 +146,7 @@ fun AlbumDetailRoute(
|
||||
fun AlbumDetailScreen(
|
||||
album: Album?,
|
||||
songs: List<Song>,
|
||||
modifier: Modifier = Modifier,
|
||||
discs: List<Disc> = emptyList(),
|
||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||
artwork: ArtworkColors?,
|
||||
@@ -160,7 +161,6 @@ fun AlbumDetailScreen(
|
||||
onMore: () -> Unit = {},
|
||||
onArtistClick: (() -> Unit)? = null,
|
||||
playingSongId: String? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val multiDisc = songs.map { it.disc ?: 1L }.distinct().size > 1
|
||||
val resources = LocalResources.current
|
||||
|
||||
@@ -48,6 +48,7 @@ fun AlbumsContent(
|
||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||
bottomInset: Dp,
|
||||
onAlbumClick: (Album) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onLongClick: (MenuTarget) -> Unit = {},
|
||||
filtered: Boolean = false,
|
||||
onClearFilters: () -> Unit = {},
|
||||
@@ -55,7 +56,6 @@ fun AlbumsContent(
|
||||
topInset: Dp = 0.dp,
|
||||
onSync: () -> Unit = {},
|
||||
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when {
|
||||
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
||||
|
||||
@@ -217,6 +217,7 @@ fun ArtistDetailRoute(
|
||||
@Composable
|
||||
fun ArtistDetailScreen(
|
||||
artist: Artist?,
|
||||
modifier: Modifier = Modifier,
|
||||
artistName: String = "",
|
||||
isAlbumArtist: Boolean = false,
|
||||
albums: List<Album>,
|
||||
@@ -232,7 +233,6 @@ fun ArtistDetailScreen(
|
||||
starred: Boolean = false,
|
||||
onToggleStar: (() -> Unit)? = null,
|
||||
onShuffle: () -> Unit = {},
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val listState = rememberLazyGridState()
|
||||
val fill = rememberViewportFill(listState)
|
||||
|
||||
@@ -45,6 +45,7 @@ fun ArtistsContent(
|
||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||
bottomInset: Dp,
|
||||
onArtistClick: (Artist) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onLongClick: (MenuTarget) -> Unit = {},
|
||||
filtered: Boolean = false,
|
||||
onClearFilters: () -> Unit = {},
|
||||
@@ -52,7 +53,6 @@ fun ArtistsContent(
|
||||
topInset: Dp = 0.dp,
|
||||
onSync: () -> Unit = {},
|
||||
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when {
|
||||
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
||||
|
||||
@@ -386,6 +386,7 @@ fun LibraryScreen(
|
||||
onPlaylistClick: (Playlist) -> Unit,
|
||||
onSync: () -> Unit,
|
||||
onOpenSettings: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onOpenSearch: () -> Unit = {},
|
||||
offline: Boolean = false,
|
||||
onExitOffline: () -> Unit = {},
|
||||
@@ -409,7 +410,6 @@ fun LibraryScreen(
|
||||
playlistDownloads: Map<String, ListDownloadStatus> = emptyMap(),
|
||||
dismissals: Flow<Unit> = emptyFlow(),
|
||||
homeContent: @Composable (topInset: Dp, bottomInset: Dp) -> Unit = { _, _ -> },
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val pagerState =
|
||||
rememberPagerState(
|
||||
@@ -831,6 +831,7 @@ private fun ListOptionsGlyph(modifier: Modifier = Modifier) {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("FrequentlyChangingValue")
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
internal fun LibraryTabs(
|
||||
|
||||
@@ -120,6 +120,7 @@ fun PlaylistDetailScreen(
|
||||
songs: LazyPagingItems<PlaylistSongItem>,
|
||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||
artwork: ArtworkColors?,
|
||||
modifier: Modifier = Modifier,
|
||||
downloads: Map<String, SongDownload> = emptyMap(),
|
||||
downloadStatus: ListDownloadStatus = ListDownloadStatus(),
|
||||
offline: Boolean = false,
|
||||
@@ -131,7 +132,6 @@ fun PlaylistDetailScreen(
|
||||
onPlay: () -> Unit = {},
|
||||
onMore: () -> Unit = {},
|
||||
playingSongId: String? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
HeroDetailScaffold(
|
||||
|
||||
@@ -44,6 +44,7 @@ fun PlaylistsContent(
|
||||
coverArt: (String?, Boolean) -> CoverArtRef?,
|
||||
bottomInset: Dp,
|
||||
onPlaylistClick: (Playlist) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onLongClick: (MenuTarget) -> Unit = {},
|
||||
filtered: Boolean = false,
|
||||
onClearFilters: () -> Unit = {},
|
||||
@@ -51,7 +52,6 @@ fun PlaylistsContent(
|
||||
topInset: Dp = 0.dp,
|
||||
onSync: () -> Unit = {},
|
||||
downloadStatuses: Map<String, ListDownloadStatus> = emptyMap(),
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when {
|
||||
items.itemCount == 0 && items.loadState.refresh is LoadState.Loading -> {
|
||||
|
||||
@@ -93,6 +93,7 @@ private fun buildVectorPath(vector: ImageVector): Path {
|
||||
@Composable
|
||||
fun SongRow(
|
||||
song: Song,
|
||||
modifier: Modifier = Modifier,
|
||||
coverArtId: String? = null,
|
||||
coverArt: ((String?, Boolean) -> CoverArtRef?)? = null,
|
||||
isPlaying: Boolean = false,
|
||||
@@ -100,7 +101,6 @@ fun SongRow(
|
||||
durationSeconds: Long? = null,
|
||||
download: SongDownload? = null,
|
||||
trailingContent: (@Composable () -> Unit)? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
ListItem(
|
||||
modifier = modifier,
|
||||
|
||||
@@ -60,10 +60,10 @@ fun MiniPlayer(
|
||||
onExpand: () -> Unit,
|
||||
onPlayPause: () -> Unit,
|
||||
onNext: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
progressInset: Boolean = false,
|
||||
onExpandDrag: (Float) -> Unit = {},
|
||||
onExpandRelease: (Float) -> Unit = {},
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val item = state.item ?: return
|
||||
var dragUpPx by remember { mutableFloatStateOf(0f) }
|
||||
|
||||
@@ -182,9 +182,9 @@ fun NowPlayingRoute(
|
||||
onQueue: () -> Unit,
|
||||
onViewAlbum: (String) -> Unit,
|
||||
onViewArtist: (String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
contextMenuHost: ContextMenuHost? = null,
|
||||
setStar: (StarType, String, Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
controller: PlaybackController = koinInject(),
|
||||
libraryRepository: LibraryRepository = koinInject(),
|
||||
downloadRepository: DownloadRepository = koinInject(),
|
||||
@@ -286,6 +286,7 @@ fun NowPlayingScreen(
|
||||
onPlayPause: () -> Unit,
|
||||
onNext: () -> Unit,
|
||||
onPrevious: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onSkipPrevious: () -> Unit = onPrevious,
|
||||
onShuffle: () -> Unit = {},
|
||||
onRepeat: () -> Unit = {},
|
||||
@@ -298,7 +299,6 @@ fun NowPlayingScreen(
|
||||
thumbnailRef: CoverArtRef? = null,
|
||||
previousArt: NowPlayingArt? = null,
|
||||
nextArt: NowPlayingArt? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val playButtonSize = 90.dp
|
||||
val playCircleDiameter = playButtonSize * 20f / 24f
|
||||
|
||||
@@ -33,6 +33,7 @@ import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -106,10 +107,10 @@ class QueueViewModel(
|
||||
var ready by mutableStateOf(false)
|
||||
private set
|
||||
|
||||
var initialIndex by mutableStateOf(0)
|
||||
var initialIndex by mutableIntStateOf(0)
|
||||
private set
|
||||
|
||||
var generation by mutableStateOf(0)
|
||||
var generation by mutableIntStateOf(0)
|
||||
private set
|
||||
|
||||
private var nextId = 0L
|
||||
@@ -562,6 +563,7 @@ internal fun dropTarget(
|
||||
return (before - if (before > from) 1 else 0) + 1
|
||||
}
|
||||
|
||||
@Suppress("ModifierParameter")
|
||||
@Composable
|
||||
private fun QueueRowItem(
|
||||
row: QueueRow,
|
||||
|
||||
@@ -59,7 +59,7 @@ import org.koin.compose.koinInject
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
|
||||
enum class SearchFilter(
|
||||
@StringRes val label: Int,
|
||||
@param:StringRes val label: Int,
|
||||
) {
|
||||
Songs(R.string.search_songs),
|
||||
Albums(R.string.resources_album_name),
|
||||
@@ -125,6 +125,7 @@ fun SearchScreen(
|
||||
query: String,
|
||||
onQueryChange: (String) -> Unit,
|
||||
results: SearchResults,
|
||||
modifier: Modifier = Modifier,
|
||||
filters: Set<SearchFilter> = ALL_FILTERS,
|
||||
onToggleFilter: (SearchFilter) -> Unit = {},
|
||||
coverArt: (String?, Boolean) -> CoverArtRef? = { _, _ -> null },
|
||||
@@ -135,7 +136,6 @@ fun SearchScreen(
|
||||
onPlaylistClick: (Playlist) -> Unit = {},
|
||||
onSongClick: (Song) -> Unit = {},
|
||||
onLongClick: (MenuTarget) -> Unit = {},
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val backLabel = stringResource(R.string.navigation_back)
|
||||
|
||||
@@ -90,8 +90,8 @@ fun AddSourceScreen(
|
||||
onSave: () -> Unit,
|
||||
onDelete: () -> Unit,
|
||||
onBack: (() -> Unit)?,
|
||||
dismissals: Flow<Unit> = emptyFlow(),
|
||||
modifier: Modifier = Modifier,
|
||||
dismissals: Flow<Unit> = emptyFlow(),
|
||||
) {
|
||||
val nameFocus = remember { FocusRequester() }
|
||||
val addressFocus = remember { FocusRequester() }
|
||||
|
||||
@@ -41,6 +41,7 @@ import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
@@ -124,6 +125,7 @@ fun SettingsScreen(
|
||||
downloadQuality: StreamQuality,
|
||||
downloadOverMetered: Boolean,
|
||||
scrobbling: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
offline: Boolean = false,
|
||||
onSelectSource: (Long) -> Unit,
|
||||
onEditServer: (Long) -> Unit,
|
||||
@@ -139,7 +141,6 @@ fun SettingsScreen(
|
||||
onOpenLicenses: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
dismissals: Flow<Unit> = emptyFlow(),
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var dialog by remember { mutableStateOf<SettingsDialog?>(null) }
|
||||
DismissOnRequest(dismissals) { dialog = null }
|
||||
@@ -397,7 +398,7 @@ private fun ConcurrencyDialog(
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
val resources = LocalResources.current
|
||||
var draft by remember(selected) { mutableStateOf(selected) }
|
||||
var draft by remember(selected) { mutableIntStateOf(selected) }
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.sync_concurrency)) },
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.luminance
|
||||
import androidx.core.graphics.get
|
||||
import androidx.palette.graphics.Palette
|
||||
import coil3.SingletonImageLoader
|
||||
import coil3.compose.LocalPlatformContext
|
||||
@@ -202,7 +203,7 @@ object ArtworkSeedCache {
|
||||
x: Int,
|
||||
y: Int,
|
||||
): 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
|
||||
}
|
||||
|
||||
|
||||
|
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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="300"
|
||||
android:viewportHeight="300">
|
||||
android:viewportHeight="300"
|
||||
tools:ignore="UnusedResources">
|
||||
<group android:translateY="40.25">
|
||||
<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"
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
<string name="navigation_tabs_library">Biblioteca</string>
|
||||
<string name="navigation_tabs_settings">Configurações</string>
|
||||
<plurals name="resources_album_count">
|
||||
<item quantity="one">%1$d album</item>
|
||||
<item quantity="other">%1$d albums</item>
|
||||
<item quantity="one">%1$d álbum</item>
|
||||
<item quantity="other">%1$d álbuns</item>
|
||||
</plurals>
|
||||
<string name="resources_filter_album">Álbum</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_username">Usuário</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_playlist_name">Playlists</string>
|
||||
</resources>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
<string name="resources_filter_genre">ประเภท</string>
|
||||
<string name="resources_filter_starred">ให้ดาว</string>
|
||||
<plurals name="resources_song_count">
|
||||
<item quantity="one">%1$d เพลง</item>
|
||||
<item quantity="other">%1$d เพลง</item>
|
||||
</plurals>
|
||||
<string name="resources_sort_by_artist">ศิลปิน</string>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<string name="navigation_tabs_library">Thư viện</string>
|
||||
<string name="navigation_tabs_settings">Cài đặt</string>
|
||||
<plurals name="resources_album_count">
|
||||
<item quantity="one">%1$d album</item>
|
||||
<item quantity="other">%1$d album</item>
|
||||
</plurals>
|
||||
<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_starred">Theo yêu thích</string>
|
||||
<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>
|
||||
</plurals>
|
||||
<string name="resources_sort_by_artist">Nghệ sĩ</string>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="app_name">subtracks</string>
|
||||
<string name="download_channel_description">Progress while songs download</string>
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
<string name="search">Search</string>
|
||||
<string name="search_this_list">Search this list</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="sort_by">Sort by</string>
|
||||
<string name="sort_ascending">Sort ascending</string>
|
||||
@@ -245,7 +245,7 @@
|
||||
<string name="error_server_unknown">Unknown error</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_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="home_section_recently_played_artists">Recently played artists</string>
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<network-security-config xmlns:tools="http://schemas.android.com/tools">
|
||||
<base-config
|
||||
cleartextTrafficPermitted="true"
|
||||
tools:ignore="InsecureBaseConfiguration">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
<certificates src="user" />
|
||||
<certificates
|
||||
src="user"
|
||||
tools:ignore="AcceptsUserCertificates" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
|
||||
@@ -34,17 +34,17 @@ class StringResourcesTest {
|
||||
val locale = parse(file)
|
||||
locale.forEach { (name, resource) ->
|
||||
val base = default[name]
|
||||
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)
|
||||
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)
|
||||
if (resource.kind == "plurals") {
|
||||
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 },
|
||||
)
|
||||
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(
|
||||
"$name placeholders differ in ${file.parentFile.name}",
|
||||
"$name placeholders differ in ${file.parentFile?.name}",
|
||||
placeholders(base.text),
|
||||
placeholders(resource.text),
|
||||
)
|
||||
|
||||
@@ -275,8 +275,8 @@ class DemoScreenshotTest {
|
||||
private fun DemoData.MiniPlayerOverlay(
|
||||
song: Song,
|
||||
album: Album,
|
||||
progressInset: Boolean = false,
|
||||
modifier: Modifier = Modifier,
|
||||
progressInset: Boolean = false,
|
||||
) {
|
||||
MiniPlayer(
|
||||
state = playbackFor(song, album),
|
||||
|
||||