parent
fa4214a0ac
commit
66e7732ec2
|
@ -76,7 +76,7 @@ style:
|
|||
UnnecessaryAbstractClass:
|
||||
active: false
|
||||
ReturnCount:
|
||||
max: 3
|
||||
max: 5
|
||||
|
||||
comments:
|
||||
active: true
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.preference.ListPreference
|
|||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import java.io.File
|
||||
import kotlin.math.ceil
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.java.KoinJavaComponent.get
|
||||
|
@ -52,7 +53,6 @@ import org.moire.ultrasonic.util.TimeSpanPreferenceDialogFragmentCompat
|
|||
import org.moire.ultrasonic.util.Util.toast
|
||||
import org.moire.ultrasonic.util.isUri
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Shows main app settings.
|
||||
|
|
|
@ -3,11 +3,11 @@ package org.moire.ultrasonic.imageloader
|
|||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Build
|
||||
import java.io.File
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
@Suppress("UtilityClassWithPublicConstructor")
|
||||
class BitmapUtils {
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat
|
|||
import com.squareup.picasso.LruCache
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.squareup.picasso.RequestCreator
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
@ -22,7 +23,6 @@ import org.moire.ultrasonic.domain.MusicDirectory
|
|||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.Util.safeClose
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Our new image loader which uses Picasso as a backend.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.moire.ultrasonic.log
|
||||
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
@ -7,7 +8,6 @@ import java.util.Locale
|
|||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.Util.safeClose
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* A Timber Tree which can be used to log to a file
|
||||
|
|
|
@ -22,9 +22,9 @@ import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
|
|||
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
||||
import org.moire.ultrasonic.util.CacheCleaner
|
||||
import org.moire.ultrasonic.util.CancellableTask
|
||||
import org.moire.ultrasonic.util.Storage
|
||||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.Settings
|
||||
import org.moire.ultrasonic.util.Storage
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import org.moire.ultrasonic.util.Util.safeClose
|
||||
import timber.log.Timber
|
||||
|
@ -73,8 +73,10 @@ class DownloadFile(
|
|||
init {
|
||||
val state: DownloadStatus
|
||||
|
||||
partialFile = FileUtil.getParentPath(saveFile) + "/" + FileUtil.getPartialFile(FileUtil.getNameFromPath(saveFile))
|
||||
completeFile = FileUtil.getParentPath(saveFile) + "/" + FileUtil.getCompleteFile(FileUtil.getNameFromPath(saveFile))
|
||||
partialFile = FileUtil.getParentPath(saveFile) + "/" +
|
||||
FileUtil.getPartialFile(FileUtil.getNameFromPath(saveFile))
|
||||
completeFile = FileUtil.getParentPath(saveFile) + "/" +
|
||||
FileUtil.getCompleteFile(FileUtil.getNameFromPath(saveFile))
|
||||
|
||||
when {
|
||||
Storage.isPathExists(saveFile) -> {
|
||||
|
@ -146,11 +148,11 @@ class DownloadFile(
|
|||
|
||||
@get:Synchronized
|
||||
val isDownloading: Boolean
|
||||
get() = downloadPrepared || (downloadTask != null && downloadTask!!.isRunning)
|
||||
get() = downloadPrepared || (downloadTask != null && downloadTask!!.isRunning)
|
||||
|
||||
@get:Synchronized
|
||||
val isDownloadCancelled: Boolean
|
||||
get() = downloadTask != null && downloadTask!!.isCancelled
|
||||
get() = downloadTask != null && downloadTask!!.isCancelled
|
||||
|
||||
fun shouldRetry(): Boolean {
|
||||
return (retryCount > 0)
|
||||
|
@ -254,9 +256,8 @@ class DownloadFile(
|
|||
val fileLength = Storage.getFromPath(partialFile)?.length ?: 0
|
||||
|
||||
needsDownloading = (
|
||||
desiredBitRate == 0 || duration == null ||
|
||||
duration == 0 || fileLength == 0L
|
||||
)
|
||||
desiredBitRate == 0 || duration == null || duration == 0 || fileLength == 0L
|
||||
)
|
||||
|
||||
if (needsDownloading) {
|
||||
// Attempt partial HTTP GET, appending to the file if it exists.
|
||||
|
@ -270,7 +271,8 @@ class DownloadFile(
|
|||
Timber.i("Executed partial HTTP GET, skipping %d bytes", fileLength)
|
||||
}
|
||||
|
||||
outputStream = Storage.getOrCreateFileFromPath(partialFile).getFileOutputStream(isPartial)
|
||||
outputStream = Storage.getOrCreateFileFromPath(partialFile)
|
||||
.getFileOutputStream(isPartial)
|
||||
|
||||
val len = inputStream.copyTo(outputStream) { totalBytesCopied ->
|
||||
setProgress(totalBytesCopied)
|
||||
|
@ -395,7 +397,7 @@ class DownloadFile(
|
|||
}
|
||||
|
||||
override val id: String
|
||||
get() = song.id
|
||||
get() = song.id
|
||||
|
||||
companion object {
|
||||
const val MAX_RETRIES = 5
|
||||
|
|
|
@ -187,7 +187,6 @@ class Downloader(
|
|||
if (listChanged) {
|
||||
updateLiveData()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun updateLiveData() {
|
||||
|
|
|
@ -19,7 +19,6 @@ import android.os.PowerManager
|
|||
import android.os.PowerManager.PARTIAL_WAKE_LOCK
|
||||
import android.os.PowerManager.WakeLock
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.moire.ultrasonic.util.Storage
|
||||
import java.net.URLEncoder
|
||||
import java.util.Locale
|
||||
import kotlin.math.abs
|
||||
|
@ -33,6 +32,7 @@ import org.moire.ultrasonic.domain.PlayerState
|
|||
import org.moire.ultrasonic.util.CancellableTask
|
||||
import org.moire.ultrasonic.util.Constants
|
||||
import org.moire.ultrasonic.util.Settings
|
||||
import org.moire.ultrasonic.util.Storage
|
||||
import org.moire.ultrasonic.util.StreamProxy
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import timber.log.Timber
|
||||
|
|
|
@ -9,7 +9,9 @@ package org.moire.ultrasonic.service
|
|||
import android.media.MediaMetadataRetriever
|
||||
import java.io.BufferedReader
|
||||
import java.io.BufferedWriter
|
||||
import org.moire.ultrasonic.util.Storage
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import java.io.FileWriter
|
||||
import java.io.InputStream
|
||||
import java.io.Reader
|
||||
import java.util.ArrayList
|
||||
|
@ -40,11 +42,9 @@ import org.moire.ultrasonic.domain.UserInfo
|
|||
import org.moire.ultrasonic.util.AbstractFile
|
||||
import org.moire.ultrasonic.util.Constants
|
||||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.Storage
|
||||
import org.moire.ultrasonic.util.Util.safeClose
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import java.io.FileWriter
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class OfflineMusicService : MusicService, KoinComponent {
|
||||
|
@ -502,7 +502,6 @@ class OfflineMusicService : MusicService, KoinComponent {
|
|||
return FileUtil.getBaseName(name)
|
||||
}
|
||||
|
||||
|
||||
private fun createEntry(file: AbstractFile, name: String?): MusicDirectory.Entry {
|
||||
val entry = MusicDirectory.Entry(file.path)
|
||||
entry.populateWithDataFrom(file, name)
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.io.IOException
|
|||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
abstract class AbstractFile: Comparable<AbstractFile> {
|
||||
abstract class AbstractFile : Comparable<AbstractFile> {
|
||||
abstract val name: String
|
||||
abstract val isDirectory: Boolean
|
||||
abstract val isFile: Boolean
|
||||
|
@ -53,4 +53,4 @@ abstract class AbstractFile: Comparable<AbstractFile> {
|
|||
}
|
||||
|
||||
abstract fun rename(pathFrom: AbstractFile, pathTo: String)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,13 @@ import org.koin.java.KoinJavaComponent.inject
|
|||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.domain.Playlist
|
||||
import org.moire.ultrasonic.service.Downloader
|
||||
import org.moire.ultrasonic.util.FileUtil.delete
|
||||
import org.moire.ultrasonic.util.FileUtil.getAlbumArtFile
|
||||
import org.moire.ultrasonic.util.FileUtil.getPlaylistDirectory
|
||||
import org.moire.ultrasonic.util.FileUtil.getPlaylistFile
|
||||
import org.moire.ultrasonic.util.FileUtil.listFiles
|
||||
import org.moire.ultrasonic.util.FileUtil.musicDirectory
|
||||
import org.moire.ultrasonic.util.Settings.cacheSizeMB
|
||||
import org.moire.ultrasonic.util.FileUtil.delete
|
||||
import org.moire.ultrasonic.util.Util.formatBytes
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import android.os.Environment
|
|||
import android.text.TextUtils
|
||||
import android.util.Pair
|
||||
import java.io.BufferedWriter
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.FileWriter
|
||||
|
@ -28,7 +29,6 @@ import org.moire.ultrasonic.app.UApp
|
|||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
import org.moire.ultrasonic.util.Util.safeClose
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
object FileUtil {
|
||||
|
@ -191,11 +191,11 @@ object FileUtil {
|
|||
if (!TextUtils.isEmpty(entry.path) && getParentPath(entry.path!!) != null) {
|
||||
val f = fileSystemSafeDir(entry.path)
|
||||
dir = String.format(
|
||||
Locale.ROOT,
|
||||
"%s/%s",
|
||||
musicDirectory.path,
|
||||
if (entry.isDirectory) f else getParentPath(f) ?: ""
|
||||
)
|
||||
Locale.ROOT,
|
||||
"%s/%s",
|
||||
musicDirectory.path,
|
||||
if (entry.isDirectory) f else getParentPath(f) ?: ""
|
||||
)
|
||||
} else {
|
||||
val artist = fileSystemSafe(entry.artist)
|
||||
var album = fileSystemSafe(entry.album)
|
||||
|
|
|
@ -9,14 +9,14 @@ package org.moire.ultrasonic.util
|
|||
|
||||
import android.content.res.AssetFileDescriptor
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import org.moire.ultrasonic.app.UApp
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import org.moire.ultrasonic.app.UApp
|
||||
|
||||
class JavaFile(override val parent: AbstractFile?, val file: File): AbstractFile() {
|
||||
class JavaFile(override val parent: AbstractFile?, val file: File) : AbstractFile() {
|
||||
override val name: String = file.name
|
||||
override val isDirectory: Boolean = file.isDirectory
|
||||
override val isFile: Boolean = file.isFile
|
||||
|
@ -33,7 +33,7 @@ class JavaFile(override val parent: AbstractFile?, val file: File): AbstractFile
|
|||
|
||||
override fun listFiles(): Array<AbstractFile> {
|
||||
val fileList = file.listFiles()
|
||||
return fileList?.map { file -> JavaFile(this, file) }?.toTypedArray() ?: emptyArray()
|
||||
return fileList?.map { file -> JavaFile(this, file) }?.toTypedArray() ?: emptyArray()
|
||||
}
|
||||
|
||||
override fun getFileOutputStream(append: Boolean): OutputStream {
|
||||
|
|
|
@ -22,4 +22,4 @@ class ResettableLazy<T>(private val initializer: () -> T) {
|
|||
fun reset() {
|
||||
lazyRef.set(lazy(initializer))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ package org.moire.ultrasonic.util
|
|||
|
||||
import android.net.Uri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import org.moire.ultrasonic.R
|
||||
import java.io.File
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.app.UApp
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -21,7 +21,7 @@ import timber.log.Timber
|
|||
object Storage {
|
||||
|
||||
val mediaRoot: ResettableLazy<AbstractFile> = ResettableLazy {
|
||||
getRoot()!!
|
||||
getRoot()!!
|
||||
}
|
||||
|
||||
private fun getRoot(): AbstractFile? {
|
||||
|
|
|
@ -1,32 +1,54 @@
|
|||
/*
|
||||
* StorageFile.kt
|
||||
* Copyright (C) 2009-2021 Ultrasonic developers
|
||||
*
|
||||
* Distributed under terms of the GNU GPLv3 license.
|
||||
*/
|
||||
|
||||
package org.moire.ultrasonic.util
|
||||
|
||||
import android.content.res.AssetFileDescriptor
|
||||
import android.net.Uri
|
||||
import android.provider.DocumentsContract
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import org.moire.ultrasonic.app.UApp
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import org.moire.ultrasonic.app.UApp
|
||||
import timber.log.Timber
|
||||
|
||||
class StorageFile(
|
||||
override val parent: StorageFile?,
|
||||
var uri: Uri,
|
||||
override val name: String,
|
||||
override val isDirectory: Boolean
|
||||
): AbstractFile() {
|
||||
private val documentFile: DocumentFile = DocumentFile.fromSingleUri(UApp.applicationContext(), uri)!!
|
||||
|
||||
) : AbstractFile() {
|
||||
override val isFile: Boolean = !isDirectory
|
||||
|
||||
override val length: Long
|
||||
get() = documentFile.length()
|
||||
get() {
|
||||
val resolver = UApp.applicationContext().contentResolver
|
||||
val column = arrayOf(DocumentsContract.Document.COLUMN_SIZE)
|
||||
resolver.query(uri, column, null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(0)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
override val lastModified: Long
|
||||
get() = documentFile.lastModified()
|
||||
get() {
|
||||
val resolver = UApp.applicationContext().contentResolver
|
||||
val column = arrayOf(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
|
||||
resolver.query(uri, column, null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(0)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
override val path: String
|
||||
get() {
|
||||
|
@ -94,7 +116,6 @@ class StorageFile(
|
|||
}
|
||||
|
||||
override fun getFromPath(path: String): StorageFile? {
|
||||
|
||||
if (storageFilePathDictionary.containsKey(path))
|
||||
return storageFilePathDictionary[path]!!
|
||||
if (notExistingPathDictionary.contains(path)) return null
|
||||
|
@ -108,7 +129,7 @@ class StorageFile(
|
|||
val fileName = FileUtil.getNameFromPath(path)
|
||||
var file: StorageFile? = null
|
||||
|
||||
Timber.v("StorageFile getFromPath path: $path")
|
||||
Timber.v("StorageFile getFromPath listing files on path: $path")
|
||||
parent.listFiles().forEach {
|
||||
if (it.name == fileName) file = it as StorageFile
|
||||
storageFilePathDictionary[it.path] = it as StorageFile
|
||||
|
@ -149,18 +170,28 @@ class StorageFile(
|
|||
|
||||
@Synchronized
|
||||
override fun rename(pathFrom: AbstractFile, pathTo: String) {
|
||||
val storagePathFrom = pathFrom as StorageFile
|
||||
if (!storagePathFrom.documentFile.exists()) throw IOException("File to rename doesn't exist")
|
||||
Timber.d("Renaming from %s to %s", storagePathFrom.path, pathTo)
|
||||
val fileFrom = pathFrom as StorageFile
|
||||
if (!fileFrom.exists()) throw IOException("File to rename doesn't exist")
|
||||
Timber.d("Renaming from %s to %s", fileFrom.path, pathTo)
|
||||
|
||||
val parentTo = getFromPath(FileUtil.getParentPath(pathTo)!!) ?: throw IOException("Destination folder doesn't exist")
|
||||
val parentTo = getFromPath(FileUtil.getParentPath(pathTo)!!)
|
||||
?: throw IOException("Destination folder doesn't exist")
|
||||
val fileTo = getFromParentAndName(parentTo, FileUtil.getNameFromPath(pathTo))
|
||||
|
||||
copyFileContents(storagePathFrom.documentFile, fileTo.documentFile)
|
||||
storagePathFrom.delete()
|
||||
copyFileContents(fileFrom, fileTo)
|
||||
fileFrom.delete()
|
||||
|
||||
notExistingPathDictionary.remove(pathTo)
|
||||
storageFilePathDictionary.remove(storagePathFrom.path)
|
||||
storageFilePathDictionary.remove(fileFrom.path)
|
||||
}
|
||||
|
||||
private fun exists(): Boolean {
|
||||
val resolver = UApp.applicationContext().contentResolver
|
||||
val column = arrayOf(DocumentsContract.Document.COLUMN_DISPLAY_NAME)
|
||||
resolver.query(uri, column, null, null, null)?.use { cursor ->
|
||||
if (cursor.count != 0) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun getChildren(): List<StorageFile> {
|
||||
|
@ -209,9 +240,9 @@ class StorageFile(
|
|||
DocumentsContract.Document.COLUMN_MIME_TYPE
|
||||
)
|
||||
|
||||
private fun copyFileContents(sourceFile: DocumentFile, destinationFile: DocumentFile) {
|
||||
UApp.applicationContext().contentResolver.openInputStream(sourceFile.uri)?.use { inputStream ->
|
||||
UApp.applicationContext().contentResolver.openOutputStream(destinationFile.uri)?.use { outputStream ->
|
||||
private fun copyFileContents(sourceFile: AbstractFile, destinationFile: AbstractFile) {
|
||||
sourceFile.getFileInputStream().use { inputStream ->
|
||||
destinationFile.getFileOutputStream(false).use { outputStream ->
|
||||
inputStream.copyInto(outputStream)
|
||||
}
|
||||
}
|
||||
|
@ -238,9 +269,7 @@ class StorageFile(
|
|||
return storageFilePathDictionary[parentPath]!!
|
||||
if (notExistingPathDictionary.contains(parentPath)) return null
|
||||
|
||||
val start = System.currentTimeMillis()
|
||||
val parent = findStorageFileForParentDirectory(parentPath)
|
||||
val end = System.currentTimeMillis()
|
||||
|
||||
if (parent == null) {
|
||||
storageFilePathDictionary.remove(parentPath)
|
||||
|
@ -253,6 +282,7 @@ class StorageFile(
|
|||
return parent
|
||||
}
|
||||
|
||||
@Suppress("NestedBlockDepth")
|
||||
private fun findStorageFileForParentDirectory(path: String): StorageFile? {
|
||||
val segments = getUriSegments(path)
|
||||
?: throw IOException("Can't get path because the root has changed")
|
||||
|
|
|
@ -2,10 +2,10 @@ package org.moire.ultrasonic.util
|
|||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import java.io.File
|
||||
import java.io.PrintWriter
|
||||
import org.moire.ultrasonic.util.Util.safeClose
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Logs the stack trace of uncaught exceptions to a file on the SD card.
|
||||
|
|
|
@ -52,7 +52,6 @@ import kotlin.math.max
|
|||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.app.UApp
|
||||
import org.moire.ultrasonic.app.UApp.Companion.applicationContext
|
||||
import org.moire.ultrasonic.domain.Bookmark
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
|
@ -757,7 +756,8 @@ object Util {
|
|||
// TODO this doesn't work for URIs
|
||||
MediaScannerConnection.scanFile(
|
||||
applicationContext(), arrayOf(file),
|
||||
null, null)
|
||||
null, null
|
||||
)
|
||||
}
|
||||
|
||||
fun getResourceFromAttribute(context: Context, resId: Int): Int {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:contentDescription="@null"
|
||||
a:src="?attr/select_folder" />
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -348,7 +348,6 @@
|
|||
<string name="share_default_greeting">Mrkni na hudbu sdílenou z %s</string>
|
||||
<string name="share_via">Sdílet skladby přes</string>
|
||||
<string name="menu.share">Sdílení</string>
|
||||
<string name="select_album_all_songs">Všechny skladby od %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Zobrazit všechny skladby umělce</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Přidat nový zápis v náhledu umělců pro přístup ke všem skladbám umělce</string>
|
||||
<string name="download.menu_show_artist">Zobrazit umělce</string>
|
||||
|
|
|
@ -343,7 +343,6 @@
|
|||
<string name="share_default_greeting">Hör dir mal die Musik an, die ich mit dir über %s geteilt habe.</string>
|
||||
<string name="share_via">Titel teilen über</string>
|
||||
<string name="menu.share">Freigabe</string>
|
||||
<string name="select_album_all_songs">Alle Titel von %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Alle Titel nach Künstler sortieren</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Einen neuen Eintrag in der Künstleransicht hinzufügen, um auf alle Lieder eines Künstlers zuzugreifen</string>
|
||||
<string name="download.menu_show_artist">Künstler zeigen</string>
|
||||
|
|
|
@ -371,7 +371,6 @@
|
|||
<string name="share_default_greeting">Echa un vistazo a esta música que te comparto desde %s</string>
|
||||
<string name="share_via">Compartir canciones vía</string>
|
||||
<string name="menu.share">Compartir</string>
|
||||
<string name="select_album_all_songs">Todas las canciones por %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Mostrar todas las canciones por artista</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Añadir nueva entrada en la vista de artista para acceder a todas las canciones de un artista</string>
|
||||
<string name="download.menu_show_artist">Mostrar artista</string>
|
||||
|
|
|
@ -362,7 +362,6 @@
|
|||
<string name="share_default_greeting">Regardez cette musique que j\'ai partagée depuis %s</string>
|
||||
<string name="share_via">Partager des titres via</string>
|
||||
<string name="menu.share">Partager</string>
|
||||
<string name="select_album_all_songs">Tous les titres de %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Voir tous les titres par artiste</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Ajouter une nouvelle entrée dans la vue artiste pour accéder à toutes les titres d\'un artiste</string>
|
||||
<string name="download.menu_show_artist">Afficher l\'artiste</string>
|
||||
|
|
|
@ -360,7 +360,6 @@
|
|||
<string name="share_default_greeting">Hallgasd meg ezt a zenét, megosztottam innen: %s</string>
|
||||
<string name="share_via">Dalok megosztása ezzel</string>
|
||||
<string name="menu.share">Megosztás</string>
|
||||
<string name="select_album_all_songs">%s minden dala</string>
|
||||
<string name="settings.show_all_songs_by_artist">Az előadó összes dalának megjelenítése</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Új bejegyzés hozzáadása az előadóhoz, az előadó összes dalának eléréséhez.</string>
|
||||
<string name="download.menu_show_artist">Ugrás az előadóhoz</string>
|
||||
|
|
|
@ -371,7 +371,6 @@
|
|||
<string name="share_default_greeting">Hé, luister eens naar de muziek die ik heb gedeeld via %s</string>
|
||||
<string name="share_via">Nummers delen via</string>
|
||||
<string name="menu.share">Delen</string>
|
||||
<string name="select_album_all_songs">Alle nummers van %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Alle nummers van artiest tonen</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Item toevoegen in artiestweergave om alle nummers van een artiest te bekijken</string>
|
||||
<string name="download.menu_show_artist">Artiest tonen</string>
|
||||
|
|
|
@ -343,7 +343,6 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników
|
|||
<string name="share_default_greeting">Sprawdź muzykę, którą udostępniam na %s</string>
|
||||
<string name="share_via">Udostępnij utwory za pomocą</string>
|
||||
<string name="menu.share">Udostępnianie</string>
|
||||
<string name="select_album_all_songs">Wszystkie utwory %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Wyświetlaj wszystkie utwory artysty</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Dodaje nową pozycję w widoku artysty z wszystkimi jego utworami</string>
|
||||
<string name="download.menu_show_artist">Wyświetlaj artystę</string>
|
||||
|
|
|
@ -364,7 +364,6 @@
|
|||
<string name="share_default_greeting">Confira esta música que compartilhei do %s</string>
|
||||
<string name="share_via">Compartilhar músicas via</string>
|
||||
<string name="menu.share">Compartilhar</string>
|
||||
<string name="select_album_all_songs">Todas as Músicas de %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Mostrar Todas as Músicas por Artista</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para acessar todas as músicas do artista</string>
|
||||
<string name="download.menu_show_artist">Mostrar Artista</string>
|
||||
|
|
|
@ -343,7 +343,6 @@
|
|||
<string name="share_default_greeting">Confira esta música que compartilhei do %s</string>
|
||||
<string name="share_via">Compartilhar músicas via</string>
|
||||
<string name="menu.share">Compartilhar</string>
|
||||
<string name="select_album_all_songs">Todas as Músicas de %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Todas as Músicas do Artista</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para ver todas as músicas do artista</string>
|
||||
<string name="download.menu_show_artist">Mostrar Artista</string>
|
||||
|
|
|
@ -362,7 +362,6 @@
|
|||
<string name="share_default_greeting">Проверьте эту музыку, с которой я поделился %s</string>
|
||||
<string name="share_via">Поделиться треками через</string>
|
||||
<string name="menu.share">Поделиться</string>
|
||||
<string name="select_album_all_songs">Все треки %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Показать все треки исполнителя</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Добавить новую запись в представлении исполнителя, чтобы получить доступ ко всем песням для исполнителя</string>
|
||||
<string name="download.menu_show_artist">Показать исполнителей</string>
|
||||
|
|
|
@ -360,7 +360,6 @@
|
|||
<string name="share_default_greeting">看看我从 %s 分享的这首音乐</string>
|
||||
<string name="share_via">分享歌曲通过</string>
|
||||
<string name="menu.share">分享</string>
|
||||
<string name="select_album_all_songs">%s 的所有歌曲</string>
|
||||
<string name="settings.show_all_songs_by_artist">按艺术家显示所有歌曲</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">在艺术家视图中添加新条目以访问艺术家的所有歌曲</string>
|
||||
<string name="download.menu_show_artist">显示艺术家</string>
|
||||
|
|
|
@ -379,7 +379,6 @@
|
|||
<string name="share_default_greeting">Check out this music I shared from %s</string>
|
||||
<string name="share_via">Share songs via</string>
|
||||
<string name="menu.share">Share</string>
|
||||
<string name="select_album_all_songs">All Songs by %s</string>
|
||||
<string name="settings.show_all_songs_by_artist">Show All Songs By Artist</string>
|
||||
<string name="settings.show_all_songs_by_artist_summary">Add new entry in artist view to access all songs for an artist</string>
|
||||
<string name="download.menu_show_artist">Show Artist</string>
|
||||
|
|
Loading…
Reference in New Issue