diff --git a/.circleci/config.yml b/.circleci/config.yml index f641578b..18e42157 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -93,14 +93,15 @@ jobs: - run: name: sign release apk command: | + export PATH="${JAVA_HOME}/bin:${PATH}" mkdir -p /tmp/ultrasonic-release - jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ~/ultrasonic/ultrasonic-keystore -storepass ${ULTRASONIC_KEYSTORE_STOREPASS} -keypass ${ULTRASONIC_KEYSTORE_KEYPASS} ultrasonic/build/outputs/apk/release/ultrasonic-release-unsigned.apk ultrasonic - jarsigner -verify ultrasonic/build/outputs/apk/release/ultrasonic-release-unsigned.apk - ${ANDROID_HOME}/build-tools/27.0.0/zipalign -v 4 ultrasonic/build/outputs/apk/release/ultrasonic-release-unsigned.apk /tmp/ultrasonic-release/ultrasonic-${CIRCLE_TAG}.apk + ${ANDROID_HOME}/build-tools/30.0.0/zipalign -v 4 ultrasonic/build/outputs/apk/release/ultrasonic-release-unsigned.apk /tmp/ultrasonic-release/ultrasonic-${CIRCLE_TAG}.apk + ${ANDROID_HOME}/build-tools/30.0.0/apksigner sign --verbose --ks ~/ultrasonic/ultrasonic-keystore --ks-pass pass:${ULTRASONIC_KEYSTORE_STOREPASS} --key-pass pass:${ULTRASONIC_KEYSTORE_KEYPASS} /tmp/ultrasonic-release/ultrasonic-${CIRCLE_TAG}.apk + ${ANDROID_HOME}/build-tools/30.0.0/apksigner verify --verbose /tmp/ultrasonic-release/ultrasonic-${CIRCLE_TAG}.apk - persist_to_workspace: root: /tmp/ultrasonic-release paths: - - ultrasonic-*.apk + - ultrasonic-*.apk* publish_github_signed_apk: docker: - image: circleci/golang @@ -125,7 +126,6 @@ workflows: branches: only: - develop - - master - generate_signed_apk: filters: tags: diff --git a/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/MusicDirectory.kt b/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/MusicDirectory.kt index e316dc42..cf28ccdd 100644 --- a/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/MusicDirectory.kt +++ b/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/MusicDirectory.kt @@ -39,15 +39,15 @@ class MusicDirectory : ArrayList() { abstract var album: String? abstract var title: String? abstract override val name: String? - abstract val discNumber: Int? + abstract var discNumber: Int? abstract var coverArt: String? - abstract val songCount: Long? - abstract val created: Date? + abstract var songCount: Long? + abstract var created: Date? abstract var artist: String? - abstract val artistId: String? - abstract val duration: Int? - abstract val year: Int? - abstract val genre: String? + abstract var artistId: String? + abstract var duration: Int? + abstract var year: Int? + abstract var genre: String? abstract var starred: Boolean abstract var path: String? abstract var closeness: Int @@ -120,15 +120,15 @@ class MusicDirectory : ArrayList() { override var album: String? = null, override var title: String? = null, override val name: String? = null, - override val discNumber: Int = 0, + override var discNumber: Int? = 0, override var coverArt: String? = null, - override val songCount: Long? = null, - override val created: Date? = null, + override var songCount: Long? = null, + override var created: Date? = null, override var artist: String? = null, - override val artistId: String? = null, - override val duration: Int = 0, - override val year: Int = 0, - override val genre: String? = null, + override var artistId: String? = null, + override var duration: Int? = 0, + override var year: Int? = 0, + override var genre: String? = null, override var starred: Boolean = false, override var path: String? = null, override var closeness: Int = 0, diff --git a/fastlane/metadata/android/en-US/changelogs/100.txt b/fastlane/metadata/android/en-US/changelogs/100.txt new file mode 100644 index 00000000..77f90ee8 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100.txt @@ -0,0 +1,4 @@ +Others + +- #671: Bump versions.mockito from 4.1.0 to 4.3.1. +- Update translations. diff --git a/fastlane/metadata/android/en-US/changelogs/99.txt b/fastlane/metadata/android/en-US/changelogs/99.txt new file mode 100644 index 00000000..ace37403 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/99.txt @@ -0,0 +1,14 @@ +Bug fixes +- #609: Weird scrobbling behaviour (offset). + +Enhancements +- #599: Moved server selector and settings to the Navigation menu. +- #600: Migrate Permission utitlity to Kotlin, increase min SDK to 17. +- #604: Implement a Download view. +- #613: targetSdkVersion must be 30 or higher. +- #622: Refactor events. +- #641: Remove feature storage. +- #642: Remove MergeAdapter and SackOfViewsAdapter. +- #649: Unify error dialog handling. +- #652: Updated custom cache location handling to remove isUri. +- #662: Improve database migrations. diff --git a/fastlane/metadata/android/es-ES/changelogs/100.txt b/fastlane/metadata/android/es-ES/changelogs/100.txt new file mode 100644 index 00000000..6f2ce6d2 --- /dev/null +++ b/fastlane/metadata/android/es-ES/changelogs/100.txt @@ -0,0 +1,4 @@ +Otros + +- #671: Actualizado versions.mockito de 4.1.0 a 4.3.1. +- Traducciones actualizadas. diff --git a/fastlane/metadata/android/es-ES/changelogs/99.txt b/fastlane/metadata/android/es-ES/changelogs/99.txt new file mode 100644 index 00000000..08363abc --- /dev/null +++ b/fastlane/metadata/android/es-ES/changelogs/99.txt @@ -0,0 +1,17 @@ +Corrección de errores +- #609: Comportamiento extraño de scrobbling (offset). + +Mejoras +- #599: Se ha movido el selector de servidor y la configuración al menú de + navegación. +- #600: Migración de la utilidad de permisos a Kotlin, aumento del SDK + mínimo a 17. +- #604: Implementar una vista de Descarga. +- #613: targetSdkVersion debe ser 30 o superior. +- #622: Refactorización de eventos. +- #641: Eliminar el almacenamiento de funciones. +- #642: Eliminar MergeAdapter y SackOfViewsAdapter. +- #649: Unificar el manejo del diálogo de error. +- #652: Manejo de ubicación de caché personalizado actualizado para eliminar + isUri. +- #662: Mejorar las migraciones de bases de datos. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 65d9e949..0c09bccb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,7 +30,7 @@ picasso = "2.71828" junit4 = "4.13.2" junit5 = "5.8.1" -mockito = "4.1.0" +mockito = "4.3.1" mockitoKotlin = "4.0.0" kluent = "1.68" apacheCodecs = "1.15" diff --git a/gradle_scripts/android-module-bootstrap.gradle b/gradle_scripts/android-module-bootstrap.gradle index 6ed10271..84aa4e41 100644 --- a/gradle_scripts/android-module-bootstrap.gradle +++ b/gradle_scripts/android-module-bootstrap.gradle @@ -40,6 +40,8 @@ android { buildFeatures { buildConfig = false + viewBinding true + dataBinding true } } diff --git a/ultrasonic/build.gradle b/ultrasonic/build.gradle index 754e308d..d9d1e948 100644 --- a/ultrasonic/build.gradle +++ b/ultrasonic/build.gradle @@ -9,8 +9,8 @@ android { defaultConfig { applicationId "org.moire.ultrasonic" - versionCode 98 - versionName "2.24.0" + versionCode 100 + versionName "3.0.1" minSdkVersion versions.minSdk targetSdkVersion versions.targetSdk @@ -48,6 +48,7 @@ android { lintOptions { baselineFile file("lint-baseline.xml") ignore 'MissingTranslation' + ignore 'UnusedQuantity' warning 'ImpliedQuantity' disable 'IconMissingDensityFolder', "VectorPath" abortOnError true @@ -57,6 +58,12 @@ android { kotlinOptions { jvmTarget = "1.8" } + + buildFeatures { + viewBinding true + dataBinding true + } + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/util/LRUCache.java b/ultrasonic/src/main/java/org/moire/ultrasonic/util/LRUCache.java deleted file mode 100644 index 2adc7cea..00000000 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/util/LRUCache.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - This file is part of Subsonic. - - Subsonic is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Subsonic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Subsonic. If not, see . - - Copyright 2009 (C) Sindre Mehus - */ -package org.moire.ultrasonic.util; - -import java.lang.ref.SoftReference; -import java.util.HashMap; -import java.util.Map; - -/** - * @author Sindre Mehus - */ -public class LRUCache -{ - - private final int capacity; - private final Map map; - - public LRUCache(int capacity) - { - map = new HashMap(capacity); - this.capacity = capacity; - } - - public synchronized V get(K key) - { - TimestampedValue value = map.get(key); - - V result = null; - if (value != null) - { - value.updateTimestamp(); - result = value.getValue(); - } - - return result; - } - - public synchronized void put(K key, V value) - { - if (map.size() >= capacity) - { - removeOldest(); - } - map.put(key, new TimestampedValue(value)); - } - - public void clear() - { - map.clear(); - } - - private void removeOldest() - { - K oldestKey = null; - long oldestTimestamp = Long.MAX_VALUE; - - for (Map.Entry entry : map.entrySet()) - { - K key = entry.getKey(); - TimestampedValue value = entry.getValue(); - if (value.getTimestamp() < oldestTimestamp) - { - oldestTimestamp = value.getTimestamp(); - oldestKey = key; - } - } - - if (oldestKey != null) - { - map.remove(oldestKey); - } - } - - private final class TimestampedValue - { - - private final SoftReference value; - private long timestamp; - - public TimestampedValue(V value) - { - this.value = new SoftReference(value); - updateTimestamp(); - } - - public V getValue() - { - return value.get(); - } - - public long getTimestamp() - { - return timestamp; - } - - public void updateTimestamp() - { - timestamp = System.currentTimeMillis(); - } - } -} \ No newline at end of file diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt index 2096928f..fb83096f 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt @@ -38,7 +38,10 @@ class UApp : MultiDexApplication() { } startKoin { - logger(TimberKoinLogger(Level.INFO)) + // TODO Currently there is a bug in Koin which makes necessary to set the loglevel to ERROR + logger(TimberKoinLogger(Level.ERROR)) + // logger(TimberKoinLogger(Level.INFO)) + // declare Android context androidContext(this@UApp) // declare modules to use diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt index ddbb62fb..2eecb7d7 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt @@ -26,6 +26,45 @@ val MIGRATION_1_2: Migration = object : Migration(1, 2) { } } +val MIGRATION_2_1: Migration = object : Migration(2, 1) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + """ + CREATE TABLE IF NOT EXISTS ServerSettingMigration ( + id INTEGER NOT NULL PRIMARY KEY, + [index] INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL, + userName TEXT NOT NULL, + password TEXT NOT NULL, + jukeboxByDefault INTEGER NOT NULL, + allowSelfSignedCertificate INTEGER NOT NULL, + ldapSupport INTEGER NOT NULL, + musicFolderId TEXT + ) + """.trimIndent() + ) + database.execSQL( + """ + INSERT INTO ServerSettingMigration ( + id, [index], name, url, userName, password, jukeboxByDefault, + allowSelfSignedCertificate, ldapSupport, musicFolderId + ) + SELECT + id, [index], name, url, userName, password, jukeboxByDefault, + allowSelfSignedCertificate, ldapSupport, musicFolderId + FROM ServerSetting + """.trimIndent() + ) + database.execSQL( + "DROP TABLE ServerSetting" + ) + database.execSQL( + "ALTER TABLE ServerSettingMigration RENAME TO ServerSetting" + ) + } +} + val MIGRATION_2_3: Migration = object : Migration(2, 3) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL( @@ -43,6 +82,46 @@ val MIGRATION_2_3: Migration = object : Migration(2, 3) { } } +val MIGRATION_3_2: Migration = object : Migration(3, 2) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + """ + CREATE TABLE IF NOT EXISTS ServerSettingMigration ( + id INTEGER NOT NULL PRIMARY KEY, + [index] INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL, + userName TEXT NOT NULL, + password TEXT NOT NULL, + jukeboxByDefault INTEGER NOT NULL, + allowSelfSignedCertificate INTEGER NOT NULL, + ldapSupport INTEGER NOT NULL, + musicFolderId TEXT, + minimumApiVersion TEXT + ) + """.trimIndent() + ) + database.execSQL( + """ + INSERT INTO ServerSettingMigration ( + id, [index], name, url, userName, password, jukeboxByDefault, + allowSelfSignedCertificate, ldapSupport, musicFolderId, minimumApiVersion + ) + SELECT + id, [index], name, url, userName, password, jukeboxByDefault, + allowSelfSignedCertificate, ldapSupport, musicFolderId, minimumApiVersion + FROM ServerSetting + """.trimIndent() + ) + database.execSQL( + "DROP TABLE ServerSetting" + ) + database.execSQL( + "ALTER TABLE ServerSettingMigration RENAME TO ServerSetting" + ) + } +} + val MIGRATION_3_4: Migration = object : Migration(3, 4) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL( @@ -50,3 +129,49 @@ val MIGRATION_3_4: Migration = object : Migration(3, 4) { ) } } + +val MIGRATION_4_3: Migration = object : Migration(4, 3) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + """ + CREATE TABLE IF NOT EXISTS ServerSettingMigration ( + id INTEGER NOT NULL PRIMARY KEY, + [index] INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL, + userName TEXT NOT NULL, + password TEXT NOT NULL, + jukeboxByDefault INTEGER NOT NULL, + allowSelfSignedCertificate INTEGER NOT NULL, + ldapSupport INTEGER NOT NULL, + musicFolderId TEXT, + minimumApiVersion TEXT, + chatSupport INTEGER, + bookmarkSupport INTEGER, + shareSupport INTEGER, + podcastSupport INTEGER + ) + """.trimIndent() + ) + database.execSQL( + """ + INSERT INTO ServerSettingMigration ( + id, [index], name, url, userName, password, jukeboxByDefault, + allowSelfSignedCertificate, ldapSupport, musicFolderId, minimumApiVersion, + chatSupport, bookmarkSupport, shareSupport, podcastSupport + ) + SELECT + id, [index], name, url, userName, password, jukeboxByDefault, + allowSelfSignedCertificate, ldapSupport, musicFolderId, minimumApiVersion, + chatSupport, bookmarkSupport, shareSupport, podcastSupport + FROM ServerSetting + """.trimIndent() + ) + database.execSQL( + "DROP TABLE ServerSetting" + ) + database.execSQL( + "ALTER TABLE ServerSettingMigration RENAME TO ServerSetting" + ) + } +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt index 79209e5b..adce9869 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt @@ -7,8 +7,11 @@ import org.koin.core.qualifier.named import org.koin.dsl.module import org.moire.ultrasonic.data.AppDatabase import org.moire.ultrasonic.data.MIGRATION_1_2 +import org.moire.ultrasonic.data.MIGRATION_2_1 import org.moire.ultrasonic.data.MIGRATION_2_3 +import org.moire.ultrasonic.data.MIGRATION_3_2 import org.moire.ultrasonic.data.MIGRATION_3_4 +import org.moire.ultrasonic.data.MIGRATION_4_3 import org.moire.ultrasonic.model.ServerSettingsModel import org.moire.ultrasonic.util.Settings @@ -28,8 +31,11 @@ val appPermanentStorage = module { DB_FILENAME ) .addMigrations(MIGRATION_1_2) + .addMigrations(MIGRATION_2_1) .addMigrations(MIGRATION_2_3) + .addMigrations(MIGRATION_3_2) .addMigrations(MIGRATION_3_4) + .addMigrations(MIGRATION_4_3) .build() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIAlbumConverter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIAlbumConverter.kt index eb42d409..5fd70782 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIAlbumConverter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIAlbumConverter.kt @@ -21,7 +21,7 @@ fun Album.toDomainEntity(): MusicDirectory.Album = MusicDirectory.Album( ) fun Album.toMusicDirectoryDomainEntity(): MusicDirectory = MusicDirectory().apply { - addAll(this@toMusicDirectoryDomainEntity.songList.map { it.toDomainEntity() }) + addAll(this@toMusicDirectoryDomainEntity.songList.map { it.toTrackEntity() }) } fun List.toDomainEntityList(): List = this.map { it.toDomainEntity() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverter.kt index e7ac4e97..19f61f32 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverter.kt @@ -10,7 +10,7 @@ fun ApiBookmark.toDomainEntity(): Bookmark = Bookmark( comment = this@toDomainEntity.comment, created = this@toDomainEntity.created?.time, changed = this@toDomainEntity.changed?.time, - entry = this@toDomainEntity.entry.toDomainEntity() + entry = this@toDomainEntity.entry.toTrackEntity() ) fun List.toDomainEntitiesList(): List = map { it.toDomainEntity() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverter.kt index adff7ee5..4999751d 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverter.kt @@ -1,5 +1,10 @@ -// Converts MusicDirectory entity from [org.moire.ultrasonic.api.subsonic.SubsonicAPIClient] -// to app domain entities. +/* + * APIMusicDirectoryConverter.kt + * Copyright (C) 2009-2021 Ultrasonic developers + * + * Distributed under terms of the GNU GPLv3 license. + */ + @file:JvmName("APIMusicDirectoryConverter") package org.moire.ultrasonic.domain @@ -9,48 +14,90 @@ import java.util.Locale import org.moire.ultrasonic.api.subsonic.models.MusicDirectory as APIMusicDirectory import org.moire.ultrasonic.api.subsonic.models.MusicDirectoryChild +/* + * Converts MusicDirectory entity from [org.moire.ultrasonic.api.subsonic.SubsonicAPIClient] + * to app domain entities. + * + * Unlike other API endpoints getMusicDirectory doesn't return instances of Albums or Songs, + * but just children, which can be albums or songs. + */ + internal val dateFormat: DateFormat by lazy { SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault()) } -fun MusicDirectoryChild.toDomainEntity(): MusicDirectory.Entry = MusicDirectory.Entry(id).apply { - parent = this@toDomainEntity.parent - isDirectory = this@toDomainEntity.isDir - title = this@toDomainEntity.title - album = this@toDomainEntity.album - albumId = this@toDomainEntity.albumId - artist = this@toDomainEntity.artist - artistId = this@toDomainEntity.artistId - track = this@toDomainEntity.track - year = this@toDomainEntity.year - genre = this@toDomainEntity.genre - contentType = this@toDomainEntity.contentType - suffix = this@toDomainEntity.suffix - transcodedContentType = this@toDomainEntity.transcodedContentType - transcodedSuffix = this@toDomainEntity.transcodedSuffix - coverArt = this@toDomainEntity.coverArt - size = this@toDomainEntity.size - duration = this@toDomainEntity.duration - bitRate = this@toDomainEntity.bitRate - path = this@toDomainEntity.path - isVideo = this@toDomainEntity.isVideo - created = this@toDomainEntity.created?.time - starred = this@toDomainEntity.starred != null - discNumber = this@toDomainEntity.discNumber - type = this@toDomainEntity.type - if (this@toDomainEntity.streamId.isNotBlank()) { - id = this@toDomainEntity.streamId - } - if (this@toDomainEntity.publishDate != null) { - artist = dateFormat.format(this@toDomainEntity.publishDate!!.time) - } - userRating = this@toDomainEntity.userRating - averageRating = this@toDomainEntity.averageRating +fun MusicDirectoryChild.toTrackEntity(): MusicDirectory.Entry = MusicDirectory.Entry(id).apply { + populateCommonProps(this, this@toTrackEntity) + populateTrackProps(this, this@toTrackEntity) } -fun List.toDomainEntityList() = this.map { it.toDomainEntity() } +fun MusicDirectoryChild.toAlbumEntity(): MusicDirectory.Album = MusicDirectory.Album(id).apply { + populateCommonProps(this, this@toAlbumEntity) +} + +private fun populateCommonProps( + entry: MusicDirectory.Child, + source: MusicDirectoryChild +) { + entry.parent = source.parent + entry.isDirectory = source.isDir + entry.title = source.title + entry.album = source.album + entry.artist = source.artist + entry.artistId = source.artistId + entry.year = source.year + entry.genre = source.genre + entry.coverArt = source.coverArt + entry.duration = source.duration + entry.path = source.path + entry.isVideo = source.isVideo + entry.created = source.created?.time + entry.starred = source.starred != null + entry.discNumber = source.discNumber + + if (source.streamId.isNotBlank()) { + entry.id = source.streamId + } + if (source.publishDate != null) { + entry.artist = dateFormat.format(source.publishDate!!.time) + } +} + +private fun populateTrackProps( + entry: MusicDirectory.Entry, + source: MusicDirectoryChild +) { + entry.size = source.size + entry.contentType = source.contentType + entry.suffix = source.suffix + entry.transcodedContentType = source.transcodedContentType + entry.transcodedSuffix = source.transcodedSuffix + entry.track = source.track + entry.albumId = source.albumId + entry.bitRate = source.bitRate + entry.type = source.type + entry.userRating = source.userRating + entry.averageRating = source.averageRating +} + +fun List.toDomainEntityList(): List { + val newList: MutableList = mutableListOf() + + forEach { + if (it.isDir) + newList.add(it.toAlbumEntity()) + else + newList.add(it.toTrackEntity()) + } + + return newList +} + +fun List.toTrackList(): List = this.map { + it.toTrackEntity() +} fun APIMusicDirectory.toDomainEntity(): MusicDirectory = MusicDirectory().apply { name = this@toDomainEntity.name - addAll(this@toDomainEntity.childList.map { it.toDomainEntity() }) + addAll(this@toDomainEntity.childList.toDomainEntityList()) } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverter.kt index 57f7e29d..7286163a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverter.kt @@ -12,7 +12,7 @@ internal val playlistDateFormat by lazy(NONE) { SimpleDateFormat.getInstance() } fun APIPlaylist.toMusicDirectoryDomainEntity(): MusicDirectory = MusicDirectory().apply { name = this@toMusicDirectoryDomainEntity.name - addAll(this@toMusicDirectoryDomainEntity.entriesList.map { it.toDomainEntity() }) + addAll(this@toMusicDirectoryDomainEntity.entriesList.map { it.toTrackEntity() }) } fun APIPlaylist.toDomainEntity(): Playlist = Playlist( diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APISearchConverter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APISearchConverter.kt index b1dfdf6a..a8833bbe 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APISearchConverter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APISearchConverter.kt @@ -9,17 +9,17 @@ import org.moire.ultrasonic.api.subsonic.models.SearchTwoResult fun APISearchResult.toDomainEntity(): SearchResult = SearchResult( emptyList(), emptyList(), - this.matchList.map { it.toDomainEntity() } + this.matchList.map { it.toTrackEntity() } ) fun SearchTwoResult.toDomainEntity(): SearchResult = SearchResult( this.artistList.map { it.toDomainEntity() }, this.albumList.map { it.toDomainEntity() }, - this.songList.map { it.toDomainEntity() } + this.songList.map { it.toTrackEntity() } ) fun SearchThreeResult.toDomainEntity(): SearchResult = SearchResult( this.artistList.map { it.toDomainEntity() }, this.albumList.map { it.toDomainEntity() }, - this.songList.map { it.toDomainEntity() } + this.songList.map { it.toTrackEntity() } ) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIShareConverter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIShareConverter.kt index 408f42f7..39162de2 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIShareConverter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIShareConverter.kt @@ -22,5 +22,5 @@ fun APIShare.toDomainEntity(): Share = Share( url = this@toDomainEntity.url, username = this@toDomainEntity.username, visitCount = this@toDomainEntity.visitCount.toLong(), - entries = this@toDomainEntity.items.toDomainEntityList().toMutableList() + entries = this@toDomainEntity.items.toTrackList().toMutableList() ) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/MainFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/MainFragment.kt index 6969a47f..127e6a2b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/MainFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/MainFragment.kt @@ -4,7 +4,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.LinearLayout import android.widget.TextView import androidx.core.view.isVisible import androidx.fragment.app.Fragment @@ -12,6 +11,7 @@ import androidx.navigation.Navigation import org.koin.core.component.KoinComponent import org.moire.ultrasonic.R import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline +import org.moire.ultrasonic.databinding.MainBinding import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.Settings import org.moire.ultrasonic.util.Util @@ -21,7 +21,6 @@ import org.moire.ultrasonic.util.Util */ class MainFragment : Fragment(), KoinComponent { - private lateinit var list: LinearLayout private lateinit var musicTitle: TextView private lateinit var artistsButton: TextView private lateinit var albumsButton: TextView @@ -41,6 +40,8 @@ class MainFragment : Fragment(), KoinComponent { private lateinit var albumsAlphaByArtistButton: TextView private lateinit var videosButton: TextView + private var binding: MainBinding? = null + override fun onCreate(savedInstanceState: Bundle?) { Util.applyTheme(this.context) super.onCreate(savedInstanceState) @@ -50,13 +51,12 @@ class MainFragment : Fragment(), KoinComponent { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { - return inflater.inflate(R.layout.main, container, false) + ): View { + binding = MainBinding.inflate(inflater, container, false) + return binding!!.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - list = view.findViewById(R.id.main_list) - setupButtons() setupClickListener() setupItemVisibility() @@ -81,25 +81,30 @@ class MainFragment : Fragment(), KoinComponent { } } + override fun onDestroyView() { + super.onDestroyView() + binding = null + } + private fun setupButtons() { - musicTitle = list.findViewById(R.id.main_music) - artistsButton = list.findViewById(R.id.main_artists_button) - albumsButton = list.findViewById(R.id.main_albums_button) - genresButton = list.findViewById(R.id.main_genres_button) - videosTitle = list.findViewById(R.id.main_videos_title) - songsTitle = list.findViewById(R.id.main_songs) - randomSongsButton = list.findViewById(R.id.main_songs_button) - songsStarredButton = list.findViewById(R.id.main_songs_starred) - albumsTitle = list.findViewById(R.id.main_albums) - albumsNewestButton = list.findViewById(R.id.main_albums_newest) - albumsRandomButton = list.findViewById(R.id.main_albums_random) - albumsHighestButton = list.findViewById(R.id.main_albums_highest) - albumsStarredButton = list.findViewById(R.id.main_albums_starred) - albumsRecentButton = list.findViewById(R.id.main_albums_recent) - albumsFrequentButton = list.findViewById(R.id.main_albums_frequent) - albumsAlphaByNameButton = list.findViewById(R.id.main_albums_alphaByName) - albumsAlphaByArtistButton = list.findViewById(R.id.main_albums_alphaByArtist) - videosButton = list.findViewById(R.id.main_videos) + musicTitle = binding!!.mainMusic + artistsButton = binding!!.mainArtistsButton + albumsButton = binding!!.mainAlbumsButton + genresButton = binding!!.mainGenresButton + videosTitle = binding!!.mainVideosTitle + songsTitle = binding!!.mainSongs + randomSongsButton = binding!!.mainSongsButton + songsStarredButton = binding!!.mainSongsStarred + albumsTitle = binding!!.mainAlbums + albumsNewestButton = binding!!.mainAlbumsNewest + albumsRandomButton = binding!!.mainAlbumsRandom + albumsHighestButton = binding!!.mainAlbumsHighest + albumsStarredButton = binding!!.mainAlbumsStarred + albumsRecentButton = binding!!.mainAlbumsRecent + albumsFrequentButton = binding!!.mainAlbumsFrequent + albumsAlphaByNameButton = binding!!.mainAlbumsAlphaByName + albumsAlphaByArtistButton = binding!!.mainAlbumsAlphaByArtist + videosButton = binding!!.mainVideos } private fun setupItemVisibility() { diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt index b551fd29..6cbc219a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt @@ -38,7 +38,6 @@ import org.moire.ultrasonic.service.MediaPlayerController import org.moire.ultrasonic.service.RxBus import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.ErrorDialog -import org.moire.ultrasonic.util.FileUtil.defaultMusicDirectory import org.moire.ultrasonic.util.FileUtil.ultrasonicDirectory import org.moire.ultrasonic.util.InfoDialog import org.moire.ultrasonic.util.MediaSessionHandler @@ -50,7 +49,6 @@ import org.moire.ultrasonic.util.Storage import org.moire.ultrasonic.util.TimeSpanPreference import org.moire.ultrasonic.util.TimeSpanPreferenceDialogFragmentCompat import org.moire.ultrasonic.util.Util.toast -import org.moire.ultrasonic.util.isUri import timber.log.Timber /** @@ -171,31 +169,36 @@ class SettingsFragment : */ override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { if ( - requestCode != SELECT_CACHE_ACTIVITY || - resultCode != Activity.RESULT_OK || - resultData == null - ) return + requestCode == SELECT_CACHE_ACTIVITY && + resultCode == Activity.RESULT_OK && + resultData != null + ) { + val read = (resultData.flags and Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0 + val write = (resultData.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0 + val persist = (resultData.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0 - val read = (resultData.flags and Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0 - val write = (resultData.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0 - val persist = (resultData.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0 + if (read && write && persist) { + if (resultData.data != null) { + // The result data contains a URI for the document or directory that + // the user selected. + val uri = resultData.data!! + val contentResolver = UApp.applicationContext().contentResolver - if (!read || !write || !persist) { + contentResolver.takePersistableUriPermission(uri, RW_FLAG) + setCacheLocation(uri.toString()) + setupCacheLocationPreference() + return + } + } ErrorDialog.Builder(context) .setMessage(R.string.settings_cache_location_error) .show() - return } - // The result data contains a URI for the document or directory that - // the user selected. - resultData.data?.also { uri -> - // Perform operations on the document using its URI. - val contentResolver = UApp.applicationContext().contentResolver - - contentResolver.takePersistableUriPermission(uri, RW_FLAG) - - setCacheLocation(uri.toString()) + if (Settings.cacheLocationUri == "") { + Settings.customCacheLocation = false + customCacheLocation?.isChecked = false + setupCacheLocationPreference() } } @@ -234,7 +237,12 @@ class SettingsFragment : RxBus.themeChangedEventPublisher.onNext(Unit) } Constants.PREFERENCES_KEY_CUSTOM_CACHE_LOCATION -> { - setupCacheLocationPreference() + if (Settings.customCacheLocation) { + selectCacheLocation() + } else { + if (Settings.cacheLocationUri != "") setCacheLocation("") + setupCacheLocationPreference() + } } } } @@ -259,34 +267,32 @@ class SettingsFragment : } private fun setupCacheLocationPreference() { - val isDefault = Settings.cacheLocation == defaultMusicDirectory.path - if (!Settings.customCacheLocation) { cacheLocation?.isVisible = false - if (!isDefault) setCacheLocation(defaultMusicDirectory.path) return } cacheLocation?.isVisible = true - val uri = Uri.parse(Settings.cacheLocation) + val uri = Uri.parse(Settings.cacheLocationUri) cacheLocation!!.summary = uri.path - cacheLocation!!.onPreferenceClickListener = - Preference.OnPreferenceClickListener { + cacheLocation!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { + selectCacheLocation() + true + } + } - // Choose a directory using the system's file picker. - val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) + private fun selectCacheLocation() { + // Choose a directory using the system's file picker. + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) - if (!isDefault && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, defaultMusicDirectory.path) - } + if (Settings.cacheLocationUri != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Settings.cacheLocationUri) + } - intent.addFlags(RW_FLAG) - intent.addFlags(PERSISTABLE_FLAG) + intent.addFlags(RW_FLAG) + intent.addFlags(PERSISTABLE_FLAG) - startActivityForResult(intent, SELECT_CACHE_ACTIVITY) - - true - } + startActivityForResult(intent, SELECT_CACHE_ACTIVITY) } private fun setupBluetoothDevicePreferences() { @@ -393,7 +399,6 @@ class SettingsFragment : sharingDefaultExpiration!!.summary = sharingDefaultExpiration!!.text sharingDefaultDescription!!.summary = sharingDefaultDescription!!.text sharingDefaultGreeting!!.summary = sharingDefaultGreeting!!.text - cacheLocation!!.summary = Settings.cacheLocation if (!mediaButtonsEnabled!!.isChecked) { lockScreenEnabled!!.isChecked = false lockScreenEnabled!!.isEnabled = false @@ -438,15 +443,16 @@ class SettingsFragment : } private fun setCacheLocation(path: String) { - if (path.isUri()) { + if (path != "") { val uri = Uri.parse(path) cacheLocation!!.summary = uri.path ?: "" } - Settings.cacheLocation = path + Settings.cacheLocationUri = path // Clear download queue. mediaPlayerControllerLazy.value.clear() + mediaPlayerControllerLazy.value.clearCaches() Storage.reset() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/model/AlbumListModel.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/model/AlbumListModel.kt index 5fd2e86d..c5fd4d41 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/model/AlbumListModel.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/model/AlbumListModel.kt @@ -65,7 +65,7 @@ class AlbumListModel(application: Application) : GenericListModel(application) { // If we are refreshing the random list, we want to avoid items moving across the screen, // by clearing the list first - if (refresh && albumListType == "random") { + if (refresh && !append && albumListType == "random") { list.postValue(listOf()) } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt index d2c0ea22..601e5817 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt @@ -44,6 +44,7 @@ class Downloader( private val jukeboxMediaPlayer: JukeboxMediaPlayer by inject() + // This cache helps us to avoid creating duplicate DownloadFile instances when showing Entries private val downloadFileCache = LRUCache(100) private var executorService: ScheduledExecutorService? = null @@ -281,6 +282,11 @@ class Downloader( @Synchronized fun getPlaylist(): List = playlist + @Synchronized + fun clearDownloadFileCache() { + downloadFileCache.clear() + } + @Synchronized fun clearPlaylist() { playlist.clear() diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerController.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerController.kt index 55cf2796..54f76a4c 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerController.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaPlayerController.kt @@ -280,6 +280,11 @@ class MediaPlayerController( jukeboxMediaPlayer.updatePlaylist() } + @Synchronized + fun clearCaches() { + downloader.clearDownloadFileCache() + } + @Synchronized fun clearIncomplete() { reset() diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt index 74c7c3ea..0289af48 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt @@ -41,6 +41,7 @@ import org.moire.ultrasonic.domain.toDomainEntity import org.moire.ultrasonic.domain.toDomainEntityList import org.moire.ultrasonic.domain.toIndexList import org.moire.ultrasonic.domain.toMusicDirectoryDomainEntity +import org.moire.ultrasonic.domain.toTrackEntity import org.moire.ultrasonic.util.FileUtil import org.moire.ultrasonic.util.Settings import timber.log.Timber @@ -317,7 +318,7 @@ open class RESTMusicService( "skipped" != podcastEntry.status && "error" != podcastEntry.status ) { - val entry = podcastEntry.toDomainEntity() + val entry = podcastEntry.toTrackEntity() entry.track = null musicDirectory.add(entry) } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LRUCache.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LRUCache.kt new file mode 100644 index 00000000..22ab7f60 --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LRUCache.kt @@ -0,0 +1,79 @@ +/* + * LRUCache.kt + * Copyright (C) 2009-2021 Ultrasonic developers + * + * Distributed under terms of the GNU GPLv3 license. + */ +package org.moire.ultrasonic.util + +import java.lang.ref.SoftReference +import java.util.HashMap + +/** + * A cache that deletes the least-recently-used items. + */ +class LRUCache(capacity: Int) { + private val capacity: Int + private val map: MutableMap + + @Synchronized + operator fun get(key: K): V? { + val value = map[key] + var result: V? = null + if (value != null) { + value.updateTimestamp() + result = value.getValue() + } + return result + } + + @Synchronized + fun put(key: K, value: V) { + if (map.size >= capacity) { + removeOldest() + } + map[key] = TimestampedValue(value) + } + + fun clear() { + map.clear() + } + + private fun removeOldest() { + var oldestKey: K? = null + var oldestTimestamp = Long.MAX_VALUE + for ((key, value) in map) { + if (value.timestamp < oldestTimestamp) { + oldestTimestamp = value.timestamp + oldestKey = key + } + } + if (oldestKey != null) { + map.remove(oldestKey) + } + } + + private inner class TimestampedValue(value: V) { + private val value: SoftReference = SoftReference(value) + + var timestamp: Long = 0 + private set + + fun getValue(): V? { + return value.get() + } + + fun updateTimestamp() { + timestamp = System.currentTimeMillis() + } + + init { + updateTimestamp() + } + } + + init { + map = HashMap(capacity) + this.capacity = capacity + } +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt index d40d039f..814a926c 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt @@ -112,9 +112,8 @@ object Settings { ) @JvmStatic - var cacheLocation by StringSetting( - Constants.PREFERENCES_KEY_CACHE_LOCATION, - FileUtil.defaultMusicDirectory.path + var cacheLocationUri by StringSetting( + Constants.PREFERENCES_KEY_CACHE_LOCATION, "" ) @JvmStatic diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt index 3ab71bd3..3af8f6fa 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt @@ -31,7 +31,8 @@ object Storage { Timber.i("StorageFile caches were reset") val root = getRoot() if (root == null) { - Settings.cacheLocation = FileUtil.defaultMusicDirectory.path + Settings.customCacheLocation = false + Settings.cacheLocationUri = "" Util.toast(UApp.applicationContext(), R.string.settings_cache_location_error) } } @@ -70,22 +71,16 @@ object Storage { } private fun getRoot(): AbstractFile? { - return if (Settings.cacheLocation.isUri()) { + return if (Settings.customCacheLocation) { val documentFile = DocumentFile.fromTreeUri( UApp.applicationContext(), - Uri.parse(Settings.cacheLocation) + Uri.parse(Settings.cacheLocationUri) ) ?: return null if (!documentFile.exists()) return null StorageFile(null, documentFile.uri, documentFile.name!!, documentFile.isDirectory) } else { - val file = File(Settings.cacheLocation) - if (!file.exists()) return null + val file = File(FileUtil.defaultMusicDirectory.path) JavaFile(null, file) } } } - -fun String.isUri(): Boolean { - // TODO is there a better way to tell apart a path and an URI? - return this.contains(':') -} diff --git a/ultrasonic/src/main/res/drawable/ic_empty.xml b/ultrasonic/src/main/res/drawable/ic_empty.xml index 74776517..5e7c170a 100644 --- a/ultrasonic/src/main/res/drawable/ic_empty.xml +++ b/ultrasonic/src/main/res/drawable/ic_empty.xml @@ -1,91 +1,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/ultrasonic/src/main/res/layout/main.xml b/ultrasonic/src/main/res/layout/main.xml index e6763155..1b384738 100644 --- a/ultrasonic/src/main/res/layout/main.xml +++ b/ultrasonic/src/main/res/layout/main.xml @@ -1,211 +1,216 @@ - + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + + + \ No newline at end of file diff --git a/ultrasonic/src/main/res/values-cs/strings.xml b/ultrasonic/src/main/res/values-cs/strings.xml index 034a12f0..11dd16e9 100644 --- a/ultrasonic/src/main/res/values-cs/strings.xml +++ b/ultrasonic/src/main/res/values-cs/strings.xml @@ -43,7 +43,6 @@ Opravdu smazat %1$s Záložka odstraněna. Záložka vytvořena na %s. - Playlist je prázdný Vzdálené ovládání není povoleno. Povolte jukebox mód v Uživatelském > Nastavení na Subsonic serveru. Vzdálené ovládání vypnuto. Hudba je přehrávána na telefonu. Vzdálené ovládání není dostupné v offline módu. @@ -129,7 +128,6 @@ Skladby Hledat Média nenalezena - %d skladeb označeno. Varování: Připojení nedostupné. Chyba: SD karta nedostupná. Přehrát vše @@ -194,9 +192,7 @@ 1 hodina Řadit skladby podle čísla CD Řadit seznam skladeb dle čísla CD a čísla skladby - Zobrazovat bitrate a příponu souboru Připojovat jméno umělce, bitrate a příponu souboru - Zobrazit stahování při přehrávání Při spuštění přehrávání přepnout na aktivitu stahování Přehrávání bez pauz Zapnout přehrávání bez pauz @@ -303,8 +299,6 @@ Obrázek umělce v seznamu umělců Zobrazí obrázek umělce v náhledu umělců pokud je dostupný Video - Streamovat media pouze přes Wi-Fi připojení - Streamovat pouze přes Wi-Fi %1$s%2$s %d kbps 0 B @@ -358,7 +352,6 @@ Všechny bluetooth přístroje Pouze audio (A2DP) přístroje Vypnuto - Jedno tlačítko přehráváná/pauza na bluetooth přístroji Povolení tohoto nastavení může pomoci zlepšit funkci spuštění/pozastavení přehrávání na starších bluetooth přístrojích Možnosti ladění aplikace Zapisovat logy ladění do souboru @@ -367,7 +360,6 @@ Zachovat soubory Smazat soubory Smazat soubory logů. - Nakonfigurované servery Opravdu chcete odebrat server? Úprava serveru @@ -383,36 +375,13 @@ %d skladba %d skladby + %d skladeb %d skladeb - - %d skladba vybrána pro připnutí. - %d skladby vybrány pro připnutí. - %d skladeb vybráno pro připnutí. - - - %d skladba vybrána pro stažení. - %d skladby vybrány pro stažení. - %d skladeb vybráno pro stažení. - - - %d skladba vybrána pro odepnutí. - %d skladby vybrány pro odepnutí. - %d skladeb vybráno pro odepnutí. - - - %d skladba přidána na konec fronty přehrávání. - %d skladyb přidány na konec fronty přehrávání. - %d skladeb přidáno na konec fronty přehrávání. - - - %d skladba přidána za aktuální skladbu. - %d skladby přidány za aktuální skladbu. - %d skladeb přidáno za aktuální skladbu. - Zbývá %d den zkušební doby Zbývají %d dny zkušební doby + Zbývá %d dní zkušební doby Zbývá %d dní zkušební doby @@ -428,11 +397,4 @@ Nekompatibilní verze. Aktualizujte prosím Ultrasonic Android aplikaci. Nekompatibilní verze. Aktualizujte prosím Subsonic server. - - Příznaky funkcí - Používat pět hvězdiček pro hodnocení skladeb - Používat pět hvězdiček pro hodnocení skladeb - namísto jednoduchého jednohvězdičkového hodnocení. - - - + diff --git a/ultrasonic/src/main/res/values-de/strings.xml b/ultrasonic/src/main/res/values-de/strings.xml index 32fedc2a..efb96fa7 100644 --- a/ultrasonic/src/main/res/values-de/strings.xml +++ b/ultrasonic/src/main/res/values-de/strings.xml @@ -14,35 +14,47 @@ Chat Ultrasonic Hauptseite Aktuelle Wiedergabe + Abspielen + Pause + Wiederholen + Zufall + Stop + Nächstes + Vorheriges Podcast Keine Podcast Kanäle registriert Podcast Wiedergabeliste Suche Nachricht senden + Album Ultrasonic + Künstler Abbrechen Kommentar Bestätigen Löschen Herunterladen Details - Mehrere Genre + Mehrere Genres Name OK Anheften + Pause + Abspielen Zuletzt spielen Als nächstes spielen + Vorheriges abspielen Jetzt spielen Zufällig spielen Öffentlich Speichern + Titel Lösen Verschiedene Künstler Möchtest du %1$s löschen Lesezeichen entfernt Lesezeichen gesetzt als %s. - Wiedergabeliste ist leer Fernbedienung ist nicht erlaubt. Bitte Jukebox Modus auf dem Subsonic Server in Benutzer > Einstellungen aktivieren. Fernbedienung ausgeschaltet. Musik wird auf dem Telefon wiedergegeben. Fernbedienungs-Modus is Offline nicht verfügbar. @@ -94,6 +106,7 @@ Genres Musik Offline + %s - Server einrichten Gemischte Wiedergabe Zufällig Mit Stern @@ -104,6 +117,7 @@ Allgemein Wiedergabeliste %s gelöscht Löschen der Wiedergabeliste %s ist fehlgeschlagen + Downloads Ende Navigation Einstellungen @@ -111,7 +125,7 @@ Medienbibliothek Offline Medien Netzwerkfehler. Neuer Versuch %1$d von %2$d. - Habe %d Künstler. + %d Künstler gefunden Lese vom Server. Lese vom Server. Fertig! Wiedergabelisten @@ -128,7 +142,6 @@ Titel Suche Keine Medien gefunden - %d Titel ausgewählt Warnung: kein Netz. Fehler: Keine SD Karte verfügbar. Alles wiedergeben @@ -136,7 +149,7 @@ Ordner wählen Keine Genres gefunden Keine Wiedergabelisten auf dem Server - Kontaktierse Server, bitte warten. + Kontaktiere Server, bitte warten. Aussehen Puffer-Länge Deaktiviert @@ -183,7 +196,7 @@ Standard Alben Standard Künstler Standard Titel - Verzeichnis Chache-Zeit + Cache-Zeit für Verzeichnisse Deaktiviert 1 Minute 10 Minuten @@ -193,9 +206,8 @@ 1 hour Sortiere Titel nach CD Sortierung der Titelliste nach CD-Nummer und Titelnummer - Bitrate und Dateiendung zeigen - Bitrate und Dateityp hinter dem Künstler anzeigen - Herunterladen bei Wiedergabe + Bitrate und Dateiendung anzeigen + Bitrate und Dateityp hinter der Künstler*in anzeigen Herunterladen zusammen mit der Wiedergabe starten. Lückenlose Wiedergabe Lückenlose Wiedergabe aktivieren @@ -206,7 +218,7 @@ Bitte eine gültige URL angeben. Bitte einen gültigen Benutzernamen eingeben (ohne führende Leerzeichen). Maximale Alben - Maximale Künstler + Max Künstler 112 Kbps 128 Kbps 160 Kbps @@ -217,12 +229,12 @@ 64 Kbps 80 Kbps 96 Kbps - Maximale Bitragte - Mobil + Max Bitrate - Mobil Unbegrenzt - Maximale Bitrate - WLAN + Max Bitrate - WLAN Maximale Titel Auf Telefon, Headset und Bluetooth-Media-Tasten reagieren - Media Tasten + Medien Tasten Netzwerk Zeitüberschreitung 105 Sekunden 120 Sekunden @@ -245,6 +257,7 @@ Unbegrenzt Fortsetzen mit Kopfhörer Die App setzt eine pausierte Wiedergabe beim Anschließen der Kopfhörer fort. + Gespielte Musik scrobbeln 1 10 100 @@ -289,6 +302,7 @@ Verbindung OK, Server nicht lizensiert. Hell Dunkel + Schwarz Thema Selbst-signierte HTTPS Zertifikate erlauben LDAP Benutzeranmeldung aktivieren @@ -298,8 +312,8 @@ Durchsuchen von ID3-Tags Nutze ID3 Tag Methode anstatt Dateisystem-Methode Film - Nur bei WLAN verbindung streamen - Nur über WLAN streamen + Medien nur über gebührenfreie Verbindungen herunterladen + Nur über WLAN herunterladen %1$s%2$s %d kbps 0 B @@ -312,11 +326,13 @@ SD Karte nicht verfügbar Keine SD Karte Standard Beschreibung einer Freigabe - Teilen + Freigaben Immer nach Details fragen Standard Ablaufzeit Dialog nicht wieder anzeigen - Ferigabeoptionen + Freigabeoptionen + Freigabe auf Server erstellen + Teilen erzeugt eine Freigabe auf dem Server und sendet die URL. Wenn ausgeschaltet, werden nur die Lied-Details geteilt. Kein Ablaufdatum Wiedergabeliste umschalten Lesezeichen setzen @@ -339,7 +355,8 @@ Ablaufzeit %s wurde von der Wiedergabeliste entfernt Wiedergabeliste teilen - Standard Begrüßung beim Teilen + Aktuelles Lied teilen + Standard Freigabe-Begrüßung Hör dir mal die Musik an, die ich mit dir über %s geteilt habe. Titel teilen über Freigabe @@ -347,11 +364,19 @@ Einen neuen Eintrag in der Künstleransicht hinzufügen, um auf alle Lieder eines Künstlers zuzugreifen Künstler zeigen Mehrere Jahre + Wiedergabe fortsetzen, wenn ein Bluetooth Gerät verbunden wurde + Wiedergabe pausieren, wenn ein Bluetooth Gerät getrennt wurde + Alle Bluetooth Geräte + Nur Audio (A2DP) Geräte + Deaktiviert + Dateien behalten + Dateien löschen + Logeinträge gelöscht Server hinzufügen Allgemeiner API Fehler: %1$s Keine Nachricht vom Server erhalten - Autorisirung mit Token ist für LDAP Benutzer nicht möglich. + Autorisierung mit Token ist für LDAP Benutzer nicht möglich. Falscher Benutzername oder Kennwort. Nicht autorisiert. Bitte die Rechte auf dem Subsonic Server überprüfen. Erforderlicher Parameter fehlt. @@ -361,10 +386,8 @@ Inkompatible Versionen. Bitte den subsonic Server aktualisieren. - Funktionseinstellungem - Verwenden Sie Fünf-Sterne-Bewertung für Songs - Verwenden Sie Fünf-Sterne-Bewertungssystem für Songs -         anstatt einfach Elemente zu markieren / zu entfernen. - + Besonderheiten + Fünf-Stern Bewertung + Benutze Bewertungssystem mit fünf Sternen anstatt Lieder mit bloß einem Stern zu markieren. diff --git a/ultrasonic/src/main/res/values-es/strings.xml b/ultrasonic/src/main/res/values-es/strings.xml index c3010b41..1b6b9f68 100644 --- a/ultrasonic/src/main/res/values-es/strings.xml +++ b/ultrasonic/src/main/res/values-es/strings.xml @@ -50,12 +50,14 @@ Reproducción aleatoria Public Guardar + Seleccionar todo Título Desanclar Varios artistas Quieres eliminar %1$s Marcador eliminado. Marcador añadido a %s. + Nada se esta descargando La lista de reproducción esta vacía El control remoto no esta habilitado. Por favor habilita el modo jukebox en Configuración > Usuarios en tu servidor de Subsonic. Control remoto apagado. La música se reproduce en tu dispositivo. @@ -108,6 +110,7 @@ Géneros Música Sin conexión + %s - Configurar servidor Reproducción aleatoria Aleatorio Me gusta @@ -120,6 +123,7 @@ Común Eliminada lista de reproducción %s Fallo al eliminar la lista de reproducción %s + Descargas Salir Navegación Configuración @@ -167,6 +171,7 @@ 5 segundos 1 minuto 8 segundos + Usar ubicación de caché personalizada Ubicación de la Caché Ubicación de la caché no válida. Usando la localización predeterminada. Tamaño de la caché @@ -209,8 +214,8 @@ 1 hora Ordenar canciones por disco Ordena las canciones por el número de disco y el número de pista - Mostrar bitrate y extensión - Añadir al nombre del artista el bitrate la extensión del fichero + Mostrar tasa de bits y la extensión del archivo + Añadir el nombre del artista con la tasa de bits y la extensión del archivo Mostrar descargas en reproducción Mostrar la actividad de descarga cuando comienza la reproducción Reproducción sin pausas @@ -294,6 +299,7 @@ Escalado de caratulas en el servidor Sin usar Nombre de usuario + Color del servidor Mostrar controles en la pantalla de bloqueo Mostrar controles de reproducción en la pantalla de bloqueo Mostrar notificación @@ -322,8 +328,8 @@ Mostrar la imagen del artista en la lista de artistas Muestra la imagen del artista en la lista de artistas si está disponible Vídeo - Solo trasmitir medios si esta conectado a la Wi-Fi - Trasmitir solo por Wi-Fi + Solo descargar medios en conexiones sin medir + Descargar solo por Wi-Fi %1$s%2$s %d kbps 0 B @@ -381,7 +387,7 @@ Todos los dispositivos Bluetooth Solo dispositivos de audio (A2DP) Deshabilitado - Reproducir / Pausar con un solo botón en el dispositivo Bluetooth + Dispositivo Bluetooth con solo un único botón Reproducir / Pausa Habilitar esto puede ayudar con los dispositivos Bluetooth más antiguos cuando la reproducción / pausa no funciona correctamente Opciones de depuración Escribir registro de depuración en un archivo @@ -392,8 +398,6 @@ Archivos de registro eliminados. Descargando medios en segundo plano… - - Servidores configurados ¿Seguro que deseas borrar el servidor? Editando servidor @@ -414,23 +418,27 @@ %d canciones - %d canción seleccionada para ser anclada. - %d canciones seleccionadas para ser ancladas. + %d canción seleccionada para ser anclada + %d canciones seleccionadas para ser ancladas - %d canción seleccionada para ser descargada. - %d canciones seleccionadas para ser descargadas. + %d canción seleccionada para ser descargada + %d canciones seleccionadas para ser descargadas - %d canción seleccionada para ser desanclada. - %d canciones seleccionadas para ser desancladas. + %d canción desanclada + %d canciones desancladas + + + %d canción eliminada + %d canciones eliminadas - %d canción añadida al final de la cola de reproducción. - %d canciones añadidas al final de la cola de reproducción. + %d canción añadida al final de la cola de reproducción + %d canciones añadidas al final de la cola de reproducción - %d canción insertada después de la canción actual. + %d canción insertada después de la canción actual %d canciones insertadas después de la canción actual. @@ -451,10 +459,10 @@ Versiones incompatibles. Por favor actualiza el servidor de Subsonic. - Funciones experimentales + Características Use cinco estrellas para las canciones Utilice el sistema de calificación de cinco estrellas para canciones - en lugar de simplemente destacar / desestimar elementos. + en lugar de simplemente marcar / desmarcar elementos. diff --git a/ultrasonic/src/main/res/values-fr/strings.xml b/ultrasonic/src/main/res/values-fr/strings.xml index c538e37a..fb150c3d 100644 --- a/ultrasonic/src/main/res/values-fr/strings.xml +++ b/ultrasonic/src/main/res/values-fr/strings.xml @@ -28,7 +28,9 @@ Playlists Recherche Envoyer un message + Album Ultrasonic + Artiste Annuler Commenter Confirmer @@ -48,12 +50,12 @@ Jouer aléatoirement Public Enregistrer + Titre Détacher Artistes divers Voulez-vous supprimer %1$s Signet supprimé. Signet ajouté à %s. - La playlist est vide La télécommande n\'est pas autorisée. Veuillez activer le mode jukebox dans Utilisateurs > Paramètres à partir de votre serveur Subsonic. Mode jukebox désactivé. La musique est jouée sur l\'appareil. Le mode jukebox n\'est pas disponible en mode déconnecté. @@ -117,6 +119,7 @@ Général Playlist %s supprimée Échec de suppression de la playlist %s + Téléchargements Quitter Navigation Paramètres @@ -141,7 +144,6 @@ Titres Recherche Aucun titre trouvé - %d pistes sélectionnées. Avertissement : Aucun réseau disponible. Erreur : Aucune carte SD disponible. Tout jouer @@ -206,7 +208,7 @@ 1 hour Trier les titres par disque Trier la liste des titres par numéro de disques/pistes - Afficher bitrate et suffixe du fichier + Afficher le Bitrate et l’extension de fichier Ajouter le nom d\'artiste, bitrate et suffixe du fichier Afficher le téléchargement lors de la lecture Aller vers les téléchargements lorsque qu\'un titre est écouté @@ -278,6 +280,8 @@ Paramètres de recherche Envoyer la pochette de l\'album via Bluetooth (peut causer l\'échec des notifications Bluetooth) Pochette de l\'album via Bluetooth + La liste de lecture ne sera pas envoyée aux appareils connectés. Cela peut restaurer la compatibilité avec les appareils AVRCP 1.3 lorsque l’affichage de la piste actuelle n’est pas mise à jour. + Désactiver l’envoi de la liste de lecture Envoyer des notifications de lecture via Bluetooth Envoyer une notification Bluetooth Gérer les serveurs @@ -289,6 +293,7 @@ Mise à l\'échelle des pochettes d\'album sur le serveur Inutilisé Nom d\'utilisateur + Couleur du serveur Boutons de contrôle sur l\'écran de verrouillage Afficher les contrôles de lecture sur l\'écran de verrouillage Notifications @@ -317,8 +322,6 @@ Afficher l’image de l’artiste dans la liste Affiche l’image de l’artiste dans la liste des artistes si celle-ci est disponible Vidéo - Lire en streaming seulement si connecté en Wi-Fi - Streaming en Wi-Fi uniquement %1$s%2$s %d Kb/s 0 o @@ -332,10 +335,13 @@ Aucune carte SD Description par défaut de la collection partagée Répartition + Toujours demander une description et une date d’expiration lors de la création d’un partage sur le serveur Toujours demander pour plus de détails Temps d\'expiration par défaut Ne montre pas de dialogue à nouveau Définir les options de partage + Créer un partage sur le serveur + Partager créera un partage sur le serveur et donnera son URL. Si désactivé, seuls les détails de la piste seront partagées. Aucune date d\'expiration Changer de vue playlist Mettre en signet @@ -358,6 +364,7 @@ Temps d\'expiration \"%s\" retiré de la playlist Partager playlist + Partager la piste actuelle Texte par défaut lors d\'un partage Regardez cette musique que j\'ai partagée depuis %s Partager des titres via @@ -372,7 +379,7 @@ Tous les appareils Bluetooth Seulement les appareils audio (A2DP) Désactivé - Bouton unique Lecture/Pause en Bluetooth + Appareil Bluetooth avec un seul bouton Lecture/Pause Activer cela peut aider sur les anciens appareils Bluetooth lorsque Lecture/Pause ne fonctionne pas correctement Paramètres de debug Enregistrer les logs de debug dans des fichiers @@ -381,7 +388,7 @@ Conserver les fichiers Supprimer les fichiers Fichiers de log supprimés - + Téléchargement des fichiers en arrière-plan… Serveurs configurés Êtes-vous sûr de vouloir supprimer ce serveur ? @@ -402,26 +409,6 @@ %d titre %d titres - - %d titre sélectionné pour être épinglé. - %d titres sélectionnés pour être épinglés. - - - %d titre sélectionné pour être téléchargé. - %d titres sélectionnés pour être téléchargés. - - - %d titre sélectionné pour être désépinglé. - %d titres sélectionnés pour être désépinglés. - - - %d titre ajouté à la fin de la file d\'attente de lecture. - %d titres ajoutés à la fin de la file d\'attente de lecture. - - - %d titre inséré après le titre actuel. - %d titres insérés après le titre actuel. - %d jour restant à la période d\'essai %d jours restant à la période d\'essai @@ -439,11 +426,4 @@ Versions incompatibles. Veuillez mette à jour l\'application Android Ultrasonic. Versions incompatibles. Veuillez mette à jour le serveur Subsonic. - - Drapeaux des fonctionnalités - Utiliser les étoiles pour noter les morceaux - Utiliser un système de notation à base d\'étoiles pour les morceaux - au lieu de simplement mettre en avant les morceaux. - - - + diff --git a/ultrasonic/src/main/res/values-hu/strings.xml b/ultrasonic/src/main/res/values-hu/strings.xml index efa3dcd0..c2ad6e60 100644 --- a/ultrasonic/src/main/res/values-hu/strings.xml +++ b/ultrasonic/src/main/res/values-hu/strings.xml @@ -53,7 +53,6 @@ Biztos, hogy törölni akarja? %1$s Könyvjelző eltávolítva. Könyvjelző beállítva %s. - A várólista üres! A távvezérlés nem áll rendelkezésre. Kérjük, engedélyezze a Jukebox módot a Felhasználók > Beállítások menüpontban, az Ön Subsonic kiszolgálóján! Távvezérlés kikapcsolása. A zenelejátszás a telefonon történik. A távvezérlés nem lehetséges kapcsolat nélküli módban! @@ -139,7 +138,6 @@ Dalok Keresés Nem található média! - %d dal kijelölve. Figyelem: Hálózat nem áll rendelkezésre! Hiba: SD kártya nem áll rendelkezésre! Összes lejátszása @@ -204,9 +202,7 @@ 1 óra Dalok rendezése albumok szerint Dalok rendezése albumsorszám és dalsorszám szerint. - Bitráta és fájlkiterjesztés megjelenítése Bitráta és fájlkiterjesztés megjelenítése az előadónév mellett. - Letöltés megjelenítése Letöltési aktivitás megjelenítése a lejátszás indításakor. Egybefüggő lejátszás Kihagyás (dalszünet) nélküli egybefüggő lejátszás (Gapless). @@ -315,8 +311,6 @@ Előadó képének megjelenítése Az előadó listában megjeleníti a képeket, amennyiben elérhetőek Videó - Streaming csak Wi-Fi hálózaton keresztül. - Streaming csak Wi-Fivel %1$s%2$s %d kbps 0 B @@ -370,7 +364,6 @@ Minden Bluetooth eszköz Csak audio (A2DP) eszközök Kikapcsolva - Egy gombos Lejátszás/Szünet a Bluetooth eszközökön Régebbi Bluetooth eszközök esetén segíthet, ha a Lejátszás/Szünet nem működik megfelelően Hibakeresési lehetőségek Hibakeresési napló írása fájlba @@ -379,8 +372,6 @@ Fájlok megtartása Fájlok törlése Naplófájlok törölve. - - Beállított szerverek Biztosan törölni szeretnéd a szervert? Szerver szerkesztése @@ -397,26 +388,6 @@ %d dal %d dal - - %d dal kijelölve tárolásra. - %d dal kijelölve tárolásra. - - - %d dal kijelölve letöltésre. - %d dal kijelölve letöltésre. - - - %d dal tárolása visszavonva. - %d dal tárolása visszavonva. - - - %d dal hozzáadva a várólistához utolsóként. - %d dal hozzáadva a várólistához utolsóként. - - - %d dal hozzáadva a várólistához következőként. - %d dal hozzáadva a várólistához következőként. - %d nap van hátra a próba időszakból. %d nap van hátra a próba időszakból. @@ -434,11 +405,4 @@ Nem kompatibilis verzió. Kérjük, frissítse az Ultrasonic Android alkalmazást! Nem kompatibilis verzió. Kérjük, frissítse a Subsonic kiszolgálót! - - Jellemzők Zászlók - Öt csillagos értékelés használata a dalokhoz - Öt csillag használata az értékeléshez az egyszerű - csillaggal jelölés helyett. - - - + diff --git a/ultrasonic/src/main/res/values-it/strings.xml b/ultrasonic/src/main/res/values-it/strings.xml index 200c0ac2..58b33cde 100644 --- a/ultrasonic/src/main/res/values-it/strings.xml +++ b/ultrasonic/src/main/res/values-it/strings.xml @@ -40,7 +40,6 @@ Vuoi eliminare %1$s Segnalibro rimosso. Segnalibro impostato su %s. - Playlist vuota Il controllo remoto non è consentito. Per favore abilita la modalità jukebox nelle Impostazioni > Utente nel server Airsonic. Controllo remoto disattivato. La musica verrà riprodotta sullo smartphone. Il controllo remoto non è disponibile nella modalità offline. @@ -125,7 +124,6 @@ Canzoni Cerca Nessun media trovato - %dtracce selezionate. Attenzione: nessuna rete disponibile. Errore: Nessuna memoria SD disponibile. Riproduci tutto @@ -190,9 +188,7 @@ 1 ora Ordina Canzoni secondo Disco Ordina lista canzoni secondo il numero disco e traccia - Visualizza Bitrate Ed Estensione File Aggiungi nome artista con bitrare ed estensione file - Visualizza Download Durante Riproduzione Passa al download quando inizia riproduzione Riproduzione Ininterrotta Abilita riproduzione ininterrotta diff --git a/ultrasonic/src/main/res/values-nl/strings.xml b/ultrasonic/src/main/res/values-nl/strings.xml index 194afb24..be74a57a 100644 --- a/ultrasonic/src/main/res/values-nl/strings.xml +++ b/ultrasonic/src/main/res/values-nl/strings.xml @@ -50,12 +50,14 @@ Willekeurig afspelen Openbaar Opslaan + Alles selecteren Titel Losmaken Verschillende artiesten Wil je %1$s verwijderen? Bladwijzer verwijderd. Bladwijzer ingesteld op %s. + Er wordt niks gedownload Lege afspeellijst Afstandsbediening wordt niet ondersteund. Schakel jukebox-modus in op je Subsonic-server via Gebruikers > Instellingen. Afstandsbediening uitgeschakeld; muziek wordt afgespeeld op de telefoon. @@ -108,6 +110,7 @@ Genres Muziek Offline + %s - Server instellen Willekeurig afspelen Willekeurig Favorieten @@ -120,6 +123,7 @@ Algemeen Afspeellijst %s verwijderd Afspeellijst %s kan niet worden verwijderd + Downloads Afsluiten Navigatie Instellingen @@ -144,7 +148,7 @@ Nummers Zoeken Geen media gevonden - %d nummers geselecteerd. + %d nummers geselecteerd Waarschuwing: geen internetverbinding. Fout: geen SD-kaart beschikbaar. Alles afspelen @@ -167,6 +171,7 @@ 5 seconden 1 minuut 8 seconden + Aangepaste cachelocatie gebruiken Cachelocatie Ongeldige cachelocatie; de standaardlocatie wordt gebruikt. Cachegrootte @@ -294,6 +299,7 @@ Verkleinde afbeeldingen ophalen van server Ongebruikt Gebruikersnaam + Serverkleur Vergrendelschermbediening tonen Toont afspeelbediening op het vergrendelscherm Melding tonen @@ -322,8 +328,8 @@ Artiestfoto tonen op artiestenlijst Toont de artiestfoto op de artiestenlijst (indien beschikbaar) Video - Alleen streamen via wifi-verbindingen - Alleen streamen via wifi + Haal media alleen op bij gebruik van onbeperkte dataverbindingen + Alleen ophalen via wifi %1$s%2$s %d kbps 0 B @@ -381,7 +387,7 @@ Alle bluetoothapparaten Alleen audio-apparaten (AD2P) Uitgeschakeld - Eén afspeel-/pauzeerknop op bluetoothapparaat + Bluetoothapparaat met één afspeel- en pauzeknop Schakel dit in bij gebruik van oudere bluetoothapparaten om de afspeel- en pauzeerknop goed te laten werken Foutopsporingsopties Foutopsporingslogboek bijhouden @@ -392,8 +398,6 @@ De logboeken zijn verwijderd. Bezig met downloaden van media op de achtergrond… - - Ingestelde servers: Weet je zeker dat je deze server wilt verwijderen? Server bewerken @@ -414,24 +418,28 @@ %d nummers - %d vast te maken nummer geselecteerd. - %d vast te maken nummers geselecteerd. + %d vast te maken nummer geselecteerd + %d vast te maken nummers geselecteerd - %d te downloaden nummer geselecteerd. - %d te downloaden nummers geselecteerd. + %d te downloaden nummer geselecteerd + %d te downloaden nummers geselecteerd - %d los te maken nummer geselecteerd. - %d los te maken nummers geselecteerd. + %d nummer losgemaakt + %d nummers losgemaakt + + + %d nummer verwijderd + %d nummers verwijderd - %d nummer toegevoegd aan het einde van afspeelwachtrij. - %d nummers toegevoegd aan het einde van afspeelwachtrij. + %d nummer toegevoegd aan het einde van afspeelwachtrij + %d nummers toegevoegd aan het einde van afspeelwachtrij - %d nummer ingevoegd na het huidige nummer. - %d nummers ingevoegd na het huidige nummer. + %d nummer ingevoegd na het huidige nummer + %d nummers ingevoegd na het huidige nummer Nog %d dag over van de proefperiode @@ -451,10 +459,10 @@ Incompatibele versies. Werk je Subsonic-server bij. - Experimentele functies - Gebruik vijf sterren voor nummers - Gebruik vijf sterren ratingsysteem voor liedjes - in plaats van items simpelweg in de hoofdrol te zetten / niet te verwijderen. + Functies + Vijf sterren gebruiken voor nummers + Toon vijf sterren om nummers te beoordelen + in plaats van items toe te voegen aan of te verwijderen uit de favorieten. diff --git a/ultrasonic/src/main/res/values-pl/strings.xml b/ultrasonic/src/main/res/values-pl/strings.xml index 8832e780..953fb967 100644 --- a/ultrasonic/src/main/res/values-pl/strings.xml +++ b/ultrasonic/src/main/res/values-pl/strings.xml @@ -42,7 +42,6 @@ Czy chcesz usunąć %1$s? Zakładka usunięta. Zakładka ustawiona na %s. - Playlista jest pusta Kontrola pilotem jest niedostępna. Proszę uruchomić tryb jukebox w Użytkownicy > Ustawienia na serwerze Subsonic. Tryb pilota jest wyłączony. Muzyka jest odtwarzana w telefonie. Pilot jest niedostępny w trybie offline. @@ -127,7 +126,6 @@ Utwory Wyszukiwanie Brak mediów - Zaznaczono %d utworów. Uwaga: sieć niedostępna. Błąd: Niedostępna karta SD. Odtwórz wszystkie @@ -192,9 +190,7 @@ 1 godzina Sortuj utwory wg dysku Sortuje listę utworów wg numeru dysku i numeru utworu - Wyświetlaj bitrate i typ pliku Dołącza bitrate i typ pliku do nazwy artysty - Wyświetlaj postęp pobierania Wyświetla postęp pobierania podczas odtwarzania Odtwarzanie bez przerw Włącz odtwarzanie bez przerw między utworami @@ -298,8 +294,6 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników Przeglądaj używając tagów ID3 Używa metod z tagów ID3 zamiast metod opartych na systemie plików Wideo - Przesyłanie mediów tylko gdy Wi-fi jest włączone - Przesyłanie tylko przez Wi-fi %1$s%2$s %d kbps 0 B @@ -355,36 +349,6 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników %d utworów %d utworów - - %d utwór zaznaczony do przypięcia. - %d utwory zaznaczone do przypięcia. - %d utworów zaznaczonych do przypięcia. - %d utworów zaznaczonych do przypięcia. - - - %d utwór zaznaczony do pobrania. - %d utwory zaznaczone do pobrania. - %d utworów zaznaczonych do pobrania. - %d utworów zaznaczonych do pobrania. - - - %d utwór zaznaczony do odpięcia. - %d utwory zaznaczone do odpięcia. - %d utworów zaznaczonych do odpięcia. - %d utworów zaznaczonych do odpięcia. - - - %d utwór dodany na koniec kolejki odtwarzania. - %d utwory dodane na koniec kolejki odtwarzania. - %d utworów dodanych na koniec kolejki odtwarzania. - %d utworów dodanych na koniec kolejki odtwarzania. - - - %d utwór wstawiony po bieżącym utworze. - %d utwory wstawione po bieżącym utworze. - %d utworów wstawionych po bieżącym utworze. - %d utworów wstawionych po bieżącym utworze. - %d dzień pozostał do zakończenia okresu próbnego %d dni pozostały do zakończenia okresu próbnego @@ -404,11 +368,4 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników Brak zgodności wersji. Uaktualnij aplikację Ultrasonic na Androida. Brak zgodności wersji. Uaktualnij serwer Subsonic. - - Flagi funkcji - Użyj pięciu gwiazdek dla utworów - W przypadku utworów użyj systemu pięciu gwiazdek - zamiast po prostu grać gwiazdkami / bez gwiazd. - - - + diff --git a/ultrasonic/src/main/res/values-pt-rBR/strings.xml b/ultrasonic/src/main/res/values-pt-rBR/strings.xml index 5fd380a2..4fbec20d 100644 --- a/ultrasonic/src/main/res/values-pt-rBR/strings.xml +++ b/ultrasonic/src/main/res/values-pt-rBR/strings.xml @@ -28,7 +28,9 @@ Playlists Pesquisa Enviar uma mensagem + Álbum Ultrasonic + Artista Cancelar Comentar Confirmar @@ -48,12 +50,12 @@ Tocar Aleatoriamente Público Salvar + Título Desafixar Vários Artistas Você quer excluir %1$s Favorito removido. Favorito marcado em %s. - Playlist está vazia Controle remoto não está permitido. Habilite o modo jukebox em Usuário > Configurações no seu servidor Subsonic. Controle remoto desligado. Música tocada no celular. Controle remoto não está disponível no modo offline. @@ -117,6 +119,7 @@ Comum Playlist excluída %s Falha ao excluir a playlist %s + Downloads Sair Navegação Configurações @@ -141,7 +144,6 @@ Músicas Pesquisar Nenhuma mídia encontrada - %d faixas selecionadas. Aviso: Nenhuma rede disponível. Erro: Nenhum cartão SD disponível. Tocar Tudo @@ -206,7 +208,7 @@ 1 hora Classificar Músicas por Álbum Classificar músicas pelo número do álbum e faixas - Mostrar Taxa de Bits e Sufixo de Arquivo + Mostrar Bitrate se Sufixo do Arquivo Adicionar o nome do artista com a taxa de bits e sufixo do arquivo Mostrar Downloads na Reprodução Transição para atividade de download quando iniciar reprodução @@ -319,8 +321,6 @@ Mostrar Foto do Artista na Lista Mostrar a imagem do artista na lista de artistas, se disponível Vídeo - Somente fazer stream de mídia se conectado por Wi-Fi - Streaming Somente por Wi-Fi %1$s%2$s %d kbps 0 B @@ -334,10 +334,13 @@ Sem cartão SD Descrição Padrão do Compartilhamento Compartilhamento + Sempre pedir descrição e expiração ao criar um compartilhamento no servidor Sempre Perguntar por Detalhes Tempo Padrão para Expirar Não mostrar este diálogo novamente Configurações de Compartilhamento + Criar Compartilhamento no Servidor + Compartilhar cria o compartilhamento no servidor e compartilha sua URL. Se desativado, somente os detalhes da música são compartilhados Não Expira Alternar Playlist Definir como Favorito @@ -360,6 +363,7 @@ Tempo até expirar \"%s\" foi removido da playlist Compartilhar Playlist + Compartilhar a Música Atual Saudação Padrão do Compartilhamento Confira esta música que compartilhei do %s Compartilhar músicas via @@ -374,7 +378,6 @@ Todos os dispositivos Bluetooth Somente dispositivos de áudio (A2DP) Desativado - Botão Único para Reproduzir/Pausar Ativar isso pode ajudar com dispositivos Bluetooth mais antigos quando Reproduzir/Pausar não funciona corretamente Opções de Depuração Log de Depuração em Arquivo @@ -385,8 +388,6 @@ Arquivos de log excluídos. Baixado mídia em segundo plano… - - Servidores Configurados Quer realmente excluir o servidor? Gerenciar Servidor @@ -406,26 +407,6 @@ %d música %d músicas - - %d música selecionada para ser fixada. - %d músicas selecionadas para serem fixadas. - - - %d música selecionada para ser baixada. - %d músicas selecionadas para serem baixadas. - - - %d música selecionada para ser desfixada. - %d músicas selecionadas para serem desfixadas. - - - %d música adicionada ao final da playlist. - %d músicas adicionadas ao final da playlist. - - - %d música adicionada após a atual. - %d músicas adicionadas após a atual. - %d dia restante do período de teste %d dias restantes do período de teste @@ -443,11 +424,4 @@ Versões incompativeis. Atualize o aplicativo Ultrasonic para Android. Versões incompativeis. Atualize o servidor Ultrasonic. - - Sinalização de Recursos - Usar Classif. 5 Estrelas para Músicas - Usar o sistema de classificação de 5 estrelas para músicas - em vez de simplesmente estrelar/não estrelar itens - - - + diff --git a/ultrasonic/src/main/res/values-pt/strings.xml b/ultrasonic/src/main/res/values-pt/strings.xml index 1a277b2d..cf4a202e 100644 --- a/ultrasonic/src/main/res/values-pt/strings.xml +++ b/ultrasonic/src/main/res/values-pt/strings.xml @@ -42,7 +42,6 @@ Você quer apagar %1$s Favorito removido. Favorito marcado em %s. - Playlist está vazia Controle remoto não está permitido. Habilite o modo jukebox em Usuário > Configurações no seu servidor Subsonic. Controle remoto desligado. Música tocada no celular. Controle remoto não está disponível no modo offline. @@ -127,7 +126,6 @@ Músicas Pesquisar Nenhuma mídia encontrada - %d faixas selecionadas. Aviso: Nenhuma rede disponível. Erro: Nenhum cartão SD disponível. Tocar Tudo @@ -192,9 +190,7 @@ 1 hora Classificar Músicas por Álbum Classificar músicas pelo número do álbum e faixas. - Taxa de Bits e Sufixo Adiciona o nome do artista com a taxa de bits e sufixo do ficheiro - Downloads na Reprodução Transição para atividade de download quando iniciar reprodução Reprodução sem Interrupção Habilita reprodução sem interrupção @@ -298,8 +294,6 @@ Navegar Usando Etiquetas ID3 Usa as etiquetas ID3 ao invés do sistema de ficheiros Vídeo - Somente fazer stream de mídia se conectado por Wi-Fi - Streaming Somente por Wi-Fi %1$s%2$s %d kbps 0 B @@ -352,26 +346,6 @@ %d música %d músicas - - %d música selecionada para ser fixada. - %d músicas selecionadas para serem fixadas. - - - %d música selecionada para ser baixada. - %d músicas selecionadas para serem baixadas. - - - %d música selecionada para ser desfixada. - %d músicas selecionadas para serem desfixadas. - - - %d música adicionada ao final da playlist. - %d músicas adicionadas ao final da playlist. - - - %d música adicionada após a atual. - %d músicas adicionadas após a atual. - %d dia restante do período de teste %d dias restantes do período de teste @@ -389,11 +363,4 @@ Versões incompativeis. Atualize o aplicativo Ultrasonic para Android. Versões incompativeis. Atualize o servidor Ultrasonic. - - Bandeiras de recursos - Use classificação de cinco estrelas para músicas - Use o sistema de classificação de cinco estrelas para músicas - em vez de simplesmente estrelar / não estrelar itens. - - - + diff --git a/ultrasonic/src/main/res/values-ru/strings.xml b/ultrasonic/src/main/res/values-ru/strings.xml index 28c81902..1ea549a1 100644 --- a/ultrasonic/src/main/res/values-ru/strings.xml +++ b/ultrasonic/src/main/res/values-ru/strings.xml @@ -53,7 +53,6 @@ Вы хотите удалить %1$s Закладка удалена Закладка установлена ​​на %s - Плейлист пустой Пульт дистанционного управления не допускается. Пожалуйста, включите режим музыкального автомата в Пользователи > Настройки на вашем Subsonic сервере. Пульт управления выключен. Музыка играет на телефоне Пульт дистанционного управления недоступен в автономном режиме. @@ -141,7 +140,6 @@ Песни Поиск Медиа не найдена - %d треки выбраны. Предупреждение: сеть недоступна. Ошибка: нет SD-карты Воспроизвести все @@ -206,9 +204,7 @@ 1 час Время кэша каталогов Сортировать список песен по номеру диска и треку - Отображать битрейт и суффикс файла Добавить имя исполнителя с битрейтом и суффиксом файла - Показать загрузки при воспроизведении Переход к загрузке активности при запуске воспроизведения Воспроизведение без промежутка Включить воспроизведение без паузы @@ -317,8 +313,6 @@ Показать изображение исполнителя в списке исполнителей Отображает изображение исполнителя в списке исполнителей, если доступно Видео - Потоковое мультимедиа только при подключении к Wi-Fi - Только потоковая передача по Wi-Fi %1$s%2$s %d kbps 0 B @@ -372,7 +366,6 @@ Все устройства Bluetooth Только аудио (A2DP) устройства Отключено - Одна кнопка Воспроизведение/Пауза на устройстве Bluetooth Включение этого может помочь со старыми устройствами Bluetooth, когда Воспроизведение/Пауза работает некорректно. Настройки отладки Записать журнал отладки в файл @@ -381,8 +374,6 @@ Сохранить файлы Удалить файлы Удаленные файлы журналов. - - Настроенные серверы Вы уверены, что хотите удалить сервер? Редактирование сервера @@ -404,36 +395,6 @@ %d песен %d песен - - %d песня выбрана для закрепления. - %d песни выбрано для закрепления. - %d песен выбрано для закрепления. - %d песен выбрано для закрепления. - - - %d песня выбрана для загрузки. - %d песни выбрано для загрузки. - %d песен выбрано для загрузки. - %d песен выбрано для загрузки. - - - %d песня выбрана для открепления. - %d песни выбрано для открепления. - %d песен выбрано для открепления. - %d песен выбрано для открепления. - - - %d песня добавлена в конец очереди воспроизведения. - %d песни добавлено в конец очереди воспроизведения. - %d песен добавлено в конец очереди воспроизведения. - %d песен добавлено в конец очереди воспроизведения. - - - %d песня вставлена после текущей песни. - %d песни вставлено после текущей песни. - %d песен вставлено после текущей песни. - %d песен вставлено после текущей песни. - Остался %d день пробного периода Осталось %d дня пробного периода @@ -453,10 +414,4 @@ Несовместимые версии. Пожалуйста, обновите приложение Ultrasonic для Android. Несовместимые версии. Пожалуйста, обновите Subsonic сервер. - - Флаги - Использовать пятизвездочный рейтинг для песен - Использовать пятизвездочную систему рейтинга для песен - вместо того, чтобы просто ставить/не ставить звезды. - - + diff --git a/ultrasonic/src/main/res/values-zh-rCN/strings.xml b/ultrasonic/src/main/res/values-zh-rCN/strings.xml index 97927f41..aae68a23 100644 --- a/ultrasonic/src/main/res/values-zh-rCN/strings.xml +++ b/ultrasonic/src/main/res/values-zh-rCN/strings.xml @@ -28,7 +28,9 @@ 播放列表 搜索 发送消息 + 专辑 Ultrasonic + 艺术家 取消 评论 确认 @@ -48,11 +50,14 @@ 随机播放 公开 保存 + 选择所有 + 标题 取消固定 群星 确定要删除 %1$s吗 书签已删除。 书签设置为 %s。 + 未下载任何内容 空的播放列表 不允许远程控制. 请在您的服务器上的 Users > Settings 打开点唱机模式。 关闭远程控制,音乐将在手机上播放 @@ -116,6 +121,7 @@ 公共 已删除播放列表 %s 播放列表删除失败%s + 下载 退出 导航 设置 @@ -140,7 +146,6 @@ 歌曲 搜索 找不到歌曲 - 已选择 %d 首曲目。 警告:网络不可用 错误:没有SD卡 播放所有 @@ -163,6 +168,7 @@ 5 秒 1 分钟 8 秒 + 使用自定义的缓存路径 缓存路径 缓存路径错误,正在使用默认路径。 缓存大小 @@ -287,6 +293,7 @@ 服务器端专辑图片缩放 未启用 用户名 + 服务器颜色 锁屏显示控制器 在锁定屏幕上显示播放控件 显示通知 @@ -315,8 +322,8 @@ 在艺术家列表中显示艺术家图片 如果可用,在艺术家列表中显示艺术家图片 视频 - 仅在连接到 WIFI 时使用流媒体 - 仅使用 WIFI + 仅未计量的网络用于下载媒体 + 仅使用Wi-Fi进行下载 %1$s%2$s %d kbps 0 B @@ -330,10 +337,13 @@ 没有 SD 卡 默认分享说明 分享 + 在服务端创建分享时始终要求提供说明和到期时间 始终询问详细信息 默认有效期 不再显示此对话框 设置分享选项 + 在服务端创建分享链接 + 分享将在服务端创建一个链接,如果不能创建,那么只会分享歌曲的信息 无期限 切换播放列表 设为书签 @@ -356,6 +366,7 @@ 有效期 %s已从播放列表中移除 分享播放列表 + 分享当前曲目 默认分享问候语 看看我从 %s 分享的这首音乐 分享歌曲通过 @@ -381,8 +392,6 @@ 删除日志文件 在后台下载媒体… - - 配置服务器 您确定要删除此服务器吗? 编辑服务器 @@ -410,6 +419,9 @@ 已选择 %d 首歌曲取消固定。 + + %d 首歌曲被删除 + 已将 %d 首歌曲添加到播放队列的末尾。 @@ -433,7 +445,7 @@ 不兼容的版本。请升级Subsonic 服务。 - 特性标志 + 特性 为歌曲使用五星评分 对歌曲使用五星级评级系统 而不是简单地为项目加星标/取消星标。 diff --git a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIAlbumConverterTest.kt b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIAlbumConverterTest.kt index 4d8eab69..b4b39932 100644 --- a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIAlbumConverterTest.kt +++ b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIAlbumConverterTest.kt @@ -51,7 +51,7 @@ class APIAlbumConverterTest { with(convertedEntity) { name `should be equal to` null size `should be equal to` entity.songList.size - this[0] `should be equal to` entity.songList[0].toDomainEntity() + this[0] `should be equal to` entity.songList[0].toTrackEntity() } } diff --git a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverterTest.kt b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverterTest.kt index b9b24fe0..f20da140 100644 --- a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverterTest.kt +++ b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIBookmarkConverterTest.kt @@ -27,7 +27,7 @@ class APIBookmarkConverterTest { comment `should be equal to` entity.comment created `should be equal to` entity.created?.time changed `should be equal to` entity.changed?.time - entry `should be equal to` entity.entry.toDomainEntity() + entry `should be equal to` entity.entry.toTrackEntity() } } diff --git a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverterTest.kt b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverterTest.kt index e1b626cb..3bb559ca 100644 --- a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverterTest.kt +++ b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIMusicDirectoryConverterTest.kt @@ -26,7 +26,7 @@ class APIMusicDirectoryConverterTest { name `should be equal to` entity.name size `should be equal to` entity.childList.size getChildren() `should be equal to` entity.childList - .map { it.toDomainEntity() }.toMutableList() + .map { it.toTrackEntity() }.toMutableList() } } @@ -44,7 +44,7 @@ class APIMusicDirectoryConverterTest { starred = Calendar.getInstance(), userRating = 3, averageRating = 2.99F ) - val convertedEntity = entity.toDomainEntity() + val convertedEntity = entity.toTrackEntity() with(convertedEntity) { id `should be equal to` entity.id @@ -84,7 +84,7 @@ class APIMusicDirectoryConverterTest { artist = "some-artist", publishDate = Calendar.getInstance() ) - val convertedEntity = entity.toDomainEntity() + val convertedEntity = entity.toTrackEntity() with(convertedEntity) { id `should be equal to` entity.streamId @@ -100,7 +100,7 @@ class APIMusicDirectoryConverterTest { domainList.size `should be equal to` entitiesList.size domainList.forEachIndexed { index, entry -> - entry `should be equal to` entitiesList[index].toDomainEntity() + entry `should be equal to` entitiesList[index].toTrackEntity() } } } diff --git a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverterTest.kt b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverterTest.kt index 7c06d540..9756af80 100644 --- a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverterTest.kt +++ b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPlaylistConverterTest.kt @@ -27,8 +27,8 @@ class APIPlaylistConverterTest { with(convertedEntity) { name `should be equal to` entity.name size `should be equal to` entity.entriesList.size - this[0] `should be equal to` entity.entriesList[0].toDomainEntity() - this[1] `should be equal to` entity.entriesList[1].toDomainEntity() + this[0] `should be equal to` entity.entriesList[0].toTrackEntity() + this[1] `should be equal to` entity.entriesList[1].toTrackEntity() } } diff --git a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APISearchConverterTest.kt b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APISearchConverterTest.kt index ff3b30f8..d54a3a76 100644 --- a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APISearchConverterTest.kt +++ b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APISearchConverterTest.kt @@ -34,7 +34,7 @@ class APISearchConverterTest { artists `should not be equal to` null artists.size `should be equal to` 0 songs.size `should be equal to` entity.matchList.size - songs[0] `should be equal to` entity.matchList[0].toDomainEntity() + songs[0] `should be equal to` entity.matchList[0].toTrackEntity() } } @@ -54,7 +54,7 @@ class APISearchConverterTest { albums.size `should be equal to` entity.albumList.size albums[0] `should be equal to` entity.albumList[0].toDomainEntity() songs.size `should be equal to` entity.songList.size - songs[0] `should be equal to` entity.songList[0].toDomainEntity() + songs[0] `should be equal to` entity.songList[0].toTrackEntity() } } @@ -74,7 +74,7 @@ class APISearchConverterTest { albums.size `should be equal to` entity.albumList.size albums[0] `should be equal to` entity.albumList[0].toDomainEntity() songs.size `should be equal to` entity.songList.size - songs[0] `should be equal to` entity.songList[0].toDomainEntity() + songs[0] `should be equal to` entity.songList[0].toTrackEntity() } } }