Merge branch 'develop' into remove-version

This commit is contained in:
Nite 2021-05-07 10:35:56 +02:00 committed by GitHub
commit 23c430e923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 260 additions and 263 deletions

View File

@ -27,7 +27,6 @@ jobs:
command: |
./gradlew ciTest testDebugUnitTest
./gradlew jacocoFullReport
bash <(curl -s https://codecov.io/bash)
- run:
name: lint
command: ./gradlew :ultrasonic:lintRelease

View File

@ -42,6 +42,7 @@ See [CONTRIBUTING](CONTRIBUTING.md).
- [Subsonic](http://www.subsonic.org/pages/index.jsp)
- [Airsonic](https://github.com/airsonic/airsonic)
- [Supysonic](https://github.com/spl0k/supysonic)
- [Ampache](https://ampache.org/)
Other *Subsonic API* implementations should work as well as long as they follow API
[documentation](http://www.subsonic.org/pages/api.jsp).

View File

@ -2,10 +2,11 @@ ext.versions = [
minSdk : 14,
targetSdk : 29,
compileSdk : 29,
gradle : '6.5',
// You need to run ./gradlew wrapper after updating the version
gradle : '7.0',
navigation : "2.3.2",
gradlePlugin : "4.1.3",
gradlePlugin : "4.2.0",
androidxcore : "1.5.0-rc01",
ktlint : "0.37.1",
ktlintGradle : "9.2.1",
@ -24,7 +25,7 @@ ext.versions = [
kotlinxCoroutines : "1.3.9",
viewModelKtx : "2.2.0",
retrofit : "2.4.0",
retrofit : "2.6.4",
jackson : "2.9.5",
okhttp : "3.12.13",
twitterSerial : "0.1.6",
@ -35,7 +36,7 @@ ext.versions = [
junit5 : "5.3.1",
mockito : "3.8.0",
mockitoKotlin : "1.5.0",
kluent : "1.35",
kluent : "1.64",
apacheCodecs : "1.10",
testRunner : "1.0.1",
robolectric : "4.5.1",

Binary file not shown.

View File

@ -1,6 +1,5 @@
#Sat Jun 13 17:12:11 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

View File

@ -6,7 +6,7 @@ jacoco {
def mergedJacocoExec = file("${project.buildDir}/jacoco/jacocoMerged.exec")
tasks.create(name: 'jacocoMergeReports', type: JacocoMerge) {
def merge = tasks.register('jacocoMergeReports', JacocoMerge) {
group = "Reporting"
description = "Merge all jacoco reports from projects into one."
@ -27,7 +27,8 @@ tasks.create(name: 'jacocoMergeReports', type: JacocoMerge) {
destinationFile(mergedJacocoExec)
}
tasks.create(name: 'jacocoFullReport', type: JacocoReport, dependsOn: 'jacocoMergeReports') {
tasks.register('jacocoFullReport', JacocoReport) {
dependsOn merge
group = "Reporting"
description = "Generate full Jacoco coverage report including all modules."
@ -46,47 +47,46 @@ tasks.create(name: 'jacocoFullReport', type: JacocoReport, dependsOn: 'jacocoMer
// Task will run anyway even if initial inputs are empty
onlyIf = { true }
doFirst {
project.subprojects { subproject ->
subproject.plugins.withId("jacoco") {
project.logger.info("${subproject.name} has Jacoco plugin applied")
subproject.plugins.withId("kotlin-android") {
project.logger.info("${subproject.name} is android project")
def mainSources = subproject.extensions.findByName("android").sourceSets['main']
project.logger.info("Android sources: ${mainSources.java.srcDirs}")
mainSources.java.srcDirs.forEach {
additionalSourceDirs(it)
}
project.logger.info("Subproject exclude: ${subproject.jacocoExclude}")
additionalClassDirs(fileTree(
dir: "${subproject.buildDir}/tmp/kotlin-classes/debug",
excludes: subproject.jacocoExclude
))
project.subprojects { subproject ->
subproject.plugins.withId("jacoco") {
project.logger.info("${subproject.name} has Jacoco plugin applied")
subproject.plugins.withId("kotlin-android") {
project.logger.info("${subproject.name} is android project")
def mainSources = subproject.extensions.findByName("android").sourceSets['main']
project.logger.info("Android sources: ${mainSources.java.srcDirs}")
mainSources.java.srcDirs.forEach {
additionalSourceDirs(it)
}
subproject.plugins.withId("kotlin") { plugin ->
project.logger.info("${subproject.name} is common kotlin project")
SourceDirectorySet mainSources = subproject.extensions.getByName("kotlin")
.sourceSets[SourceSet.MAIN_SOURCE_SET_NAME]
.kotlin
mainSources.srcDirs.forEach {
project.logger.debug("Adding sources: $it")
additionalSourceDirs(it)
}
project.logger.info("Subproject exclude: ${subproject.jacocoExclude}")
additionalClassDirs(fileTree(
dir: "${subproject.buildDir}/classes/kotlin/main",
excludes: subproject.jacocoExclude
))
project.logger.info("Subproject exclude: ${subproject.jacocoExclude}")
additionalClassDirs(fileTree(
dir: "${subproject.buildDir}/tmp/kotlin-classes/debug",
excludes: subproject.jacocoExclude
))
}
subproject.plugins.withId("kotlin") { plugin ->
project.logger.info("${subproject.name} is common kotlin project")
SourceDirectorySet mainSources = subproject.extensions.getByName("kotlin")
.sourceSets[SourceSet.MAIN_SOURCE_SET_NAME]
.kotlin
mainSources.srcDirs.forEach {
project.logger.debug("Adding sources: $it")
additionalSourceDirs(it)
}
project.logger.info("Subproject exclude: ${subproject.jacocoExclude}")
additionalClassDirs(fileTree(
dir: "${subproject.buildDir}/classes/kotlin/main",
excludes: subproject.jacocoExclude
))
}
subproject.tasks.withType(Test) { task ->
File destFile = task.extensions.getByType(JacocoTaskExtension.class).destinationFile
if (destFile.exists() && !task.name.contains("Release")) {
project.logger.info("Adding execution data: $destFile")
executionData(destFile)
}
subproject.tasks.withType(Test) { task ->
File destFile = task.extensions.getByType(JacocoTaskExtension.class).destinationFile
if (destFile.exists() && !task.name.contains("Release")) {
project.logger.info("Adding execution data: $destFile")
executionData(destFile)
}
}
}
}
}

View File

@ -10,9 +10,6 @@ sourceSets {
test.resources.srcDirs += "${projectDir}/src/integrationTest/resources"
}
test {
useJUnitPlatform()
}
dependencies {
api other.kotlinStdlib
@ -44,15 +41,17 @@ jacocoTestReport {
}
}
test.finalizedBy jacocoTestReport
test {
tasks.named("test").configure {
useJUnitPlatform()
jacoco {
excludes += jacocoExclude
includeNoLocationClasses = true
}
finalizedBy jacocoTestReport
}
tasks.create(name: "ciTest", dependsOn: "test") {
tasks.register("ciTest") {
dependsOn test
group = "Verification"
description = "Special task for CI that calls all tests in pure kotlin modules"
}

53
gradlew vendored
View File

@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

43
gradlew.bat vendored
View File

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell

View File

@ -320,7 +320,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
// Execute a ping to retrieve the API version.
// This is accepted to fail if the authentication is incorrect yet.
var pingResponse = subsonicApiClient.api.ping().execute()
if (pingResponse?.body() != null) {
if (pingResponse.body() != null) {
val restApiVersion = pingResponse.body()!!.version.restApiVersion
currentServerSetting!!.minimumApiVersion = restApiVersion
Timber.i("Server minimum API version set to %s", restApiVersion)

View File

@ -93,7 +93,6 @@ class SelectAlbumFragment : Fragment() {
private var cancellationToken: CancellationToken? = null
private val activeServerProvider: ActiveServerProvider by inject()
private val serverSettingsModel: ServerSettingsModel by viewModel()
private val model: SelectAlbumModel by viewModels()
private val random: Random = SecureRandom()
@ -133,6 +132,7 @@ class SelectAlbumFragment : Fragment() {
requireContext(), view as ViewGroup
) { selectedFolderId ->
if (!isOffline(context)) {
val serverSettingsModel: ServerSettingsModel by viewModel()
val currentSetting = activeServerProvider.getActiveServer()
currentSetting.musicFolderId = selectedFolderId
serverSettingsModel.updateItem(currentSetting)
@ -230,31 +230,32 @@ class SelectAlbumFragment : Fragment() {
}
private fun updateDisplay(refresh: Boolean) {
val id = requireArguments().getString(Constants.INTENT_EXTRA_NAME_ID)
val isAlbum = requireArguments().getBoolean(Constants.INTENT_EXTRA_NAME_IS_ALBUM, false)
val name = requireArguments().getString(Constants.INTENT_EXTRA_NAME_NAME)
val parentId = requireArguments().getString(Constants.INTENT_EXTRA_NAME_PARENT_ID)
val playlistId = requireArguments().getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID)
val podcastChannelId = requireArguments().getString(
val args = requireArguments()
val id = args.getString(Constants.INTENT_EXTRA_NAME_ID)
val isAlbum = args.getBoolean(Constants.INTENT_EXTRA_NAME_IS_ALBUM, false)
val name = args.getString(Constants.INTENT_EXTRA_NAME_NAME)
val parentId = args.getString(Constants.INTENT_EXTRA_NAME_PARENT_ID)
val playlistId = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID)
val podcastChannelId = args.getString(
Constants.INTENT_EXTRA_NAME_PODCAST_CHANNEL_ID
)
val playlistName = requireArguments().getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME)
val shareId = requireArguments().getString(Constants.INTENT_EXTRA_NAME_SHARE_ID)
val shareName = requireArguments().getString(Constants.INTENT_EXTRA_NAME_SHARE_NAME)
val albumListType = requireArguments().getString(
val playlistName = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME)
val shareId = args.getString(Constants.INTENT_EXTRA_NAME_SHARE_ID)
val shareName = args.getString(Constants.INTENT_EXTRA_NAME_SHARE_NAME)
val albumListType = args.getString(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE
)
val genreName = requireArguments().getString(Constants.INTENT_EXTRA_NAME_GENRE_NAME)
val albumListTitle = requireArguments().getInt(
val genreName = args.getString(Constants.INTENT_EXTRA_NAME_GENRE_NAME)
val albumListTitle = args.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, 0
)
val getStarredTracks = requireArguments().getInt(Constants.INTENT_EXTRA_NAME_STARRED, 0)
val getVideos = requireArguments().getInt(Constants.INTENT_EXTRA_NAME_VIDEOS, 0)
val getRandomTracks = requireArguments().getInt(Constants.INTENT_EXTRA_NAME_RANDOM, 0)
val albumListSize = requireArguments().getInt(
val getStarredTracks = args.getInt(Constants.INTENT_EXTRA_NAME_STARRED, 0)
val getVideos = args.getInt(Constants.INTENT_EXTRA_NAME_VIDEOS, 0)
val getRandomTracks = args.getInt(Constants.INTENT_EXTRA_NAME_RANDOM, 0)
val albumListSize = args.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0
)
val albumListOffset = requireArguments().getInt(
val albumListOffset = args.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
)

View File

@ -54,50 +54,49 @@ class SelectAlbumModel(application: Application) : AndroidViewModel(application)
parentId: String?
) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
var root = MusicDirectory()
val service = MusicServiceFactory.getMusicService(context)
if (allSongsId == id) {
val musicDirectory = service.getMusicDirectory(
parentId, name, refresh, context
)
var root = MusicDirectory()
val songs: MutableList<MusicDirectory.Entry> = LinkedList()
getSongsRecursively(musicDirectory, songs)
if (allSongsId == id) {
val musicDirectory = service.getMusicDirectory(
parentId, name, refresh, context
)
for (song in songs) {
if (!song.isDirectory) {
root.addChild(song)
}
}
} else {
val musicDirectory = service.getMusicDirectory(id, name, refresh, context)
val songs: MutableList<MusicDirectory.Entry> = LinkedList()
getSongsRecursively(musicDirectory, songs)
if (Util.getShouldShowAllSongsByArtist(context) &&
musicDirectory.findChild(allSongsId) == null &&
hasOnlyFolders(musicDirectory)
) {
val allSongs = MusicDirectory.Entry()
allSongs.isDirectory = true
allSongs.artist = name
allSongs.parent = id
allSongs.id = allSongsId
allSongs.title = String.format(
context.resources.getString(R.string.select_album_all_songs), name
)
root.addChild(allSongs)
root.addAll(musicDirectory.getChildren())
} else {
root = musicDirectory
for (song in songs) {
if (!song.isDirectory) {
root.addChild(song)
}
}
} else {
val musicDirectory = service.getMusicDirectory(id, name, refresh, context)
currentDirectory.postValue(root)
if (Util.getShouldShowAllSongsByArtist(context) &&
musicDirectory.findChild(allSongsId) == null &&
hasOnlyFolders(musicDirectory)
) {
val allSongs = MusicDirectory.Entry()
allSongs.isDirectory = true
allSongs.artist = name
allSongs.parent = id
allSongs.id = allSongsId
allSongs.title = String.format(
context.resources.getString(R.string.select_album_all_songs), name
)
root.addChild(allSongs)
root.addAll(musicDirectory.getChildren())
} else {
root = musicDirectory
}
}
currentDirectory.postValue(root)
}
}
@ -128,107 +127,99 @@ class SelectAlbumModel(application: Application) : AndroidViewModel(application)
suspend fun getArtist(refresh: Boolean, id: String?, name: String?) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val service = MusicServiceFactory.getMusicService(context)
var root = MusicDirectory()
var root = MusicDirectory()
val musicDirectory = service.getArtist(id, name, refresh, context)
val musicDirectory = service.getArtist(id, name, refresh, context)
if (Util.getShouldShowAllSongsByArtist(context) &&
musicDirectory.findChild(allSongsId) == null &&
hasOnlyFolders(musicDirectory)
) {
val allSongs = MusicDirectory.Entry()
if (Util.getShouldShowAllSongsByArtist(context) &&
musicDirectory.findChild(allSongsId) == null &&
hasOnlyFolders(musicDirectory)
) {
val allSongs = MusicDirectory.Entry()
allSongs.isDirectory = true
allSongs.artist = name
allSongs.parent = id
allSongs.id = allSongsId
allSongs.title = String.format(
context.resources.getString(R.string.select_album_all_songs), name
)
allSongs.isDirectory = true
allSongs.artist = name
allSongs.parent = id
allSongs.id = allSongsId
allSongs.title = String.format(
context.resources.getString(R.string.select_album_all_songs), name
)
root.addFirst(allSongs)
root.addAll(musicDirectory.getChildren())
} else {
root = musicDirectory
}
currentDirectory.postValue(root)
root.addFirst(allSongs)
root.addAll(musicDirectory.getChildren())
} else {
root = musicDirectory
}
currentDirectory.postValue(root)
}
}
suspend fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory: MusicDirectory
val musicDirectory: MusicDirectory
musicDirectory = if (allSongsId == id) {
val root = MusicDirectory()
musicDirectory = if (allSongsId == id) {
val root = MusicDirectory()
val songs: MutableCollection<MusicDirectory.Entry> = LinkedList()
val artist = service.getArtist(parentId, "", false, context)
val songs: MutableCollection<MusicDirectory.Entry> = LinkedList()
val artist = service.getArtist(parentId, "", false, context)
for ((id1) in artist.getChildren()) {
if (allSongsId != id1) {
val albumDirectory = service.getAlbum(
id1, "", false, context
)
for ((id1) in artist.getChildren()) {
if (allSongsId != id1) {
val albumDirectory = service.getAlbum(
id1, "", false, context
)
for (song in albumDirectory.getChildren()) {
if (!song.isVideo) {
songs.add(song)
}
for (song in albumDirectory.getChildren()) {
if (!song.isVideo) {
songs.add(song)
}
}
}
for (song in songs) {
if (!song.isDirectory) {
root.addChild(song)
}
}
root
} else {
service.getAlbum(id, name, refresh, context)
}
currentDirectory.postValue(musicDirectory)
for (song in songs) {
if (!song.isDirectory) {
root.addChild(song)
}
}
root
} else {
service.getAlbum(id, name, refresh, context)
}
currentDirectory.postValue(musicDirectory)
}
}
suspend fun getSongsForGenre(genre: String, count: Int, offset: Int) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getSongsByGenre(genre, count, offset, context)
songsForGenre.postValue(musicDirectory)
}
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getSongsByGenre(genre, count, offset, context)
songsForGenre.postValue(musicDirectory)
}
}
suspend fun getStarred() {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory: MusicDirectory
val context = context
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory: MusicDirectory
val context = context
if (Util.getShouldUseId3Tags(context)) {
musicDirectory = Util.getSongsFromSearchResult(service.getStarred2(context))
} else {
musicDirectory = Util.getSongsFromSearchResult(service.getStarred(context))
}
currentDirectory.postValue(musicDirectory)
if (Util.getShouldUseId3Tags(context)) {
musicDirectory = Util.getSongsFromSearchResult(service.getStarred2(context))
} else {
musicDirectory = Util.getSongsFromSearchResult(service.getStarred(context))
}
currentDirectory.postValue(musicDirectory)
}
}
@ -236,68 +227,58 @@ class SelectAlbumModel(application: Application) : AndroidViewModel(application)
showHeader = false
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
currentDirectory.postValue(service.getVideos(refresh, context))
}
val service = MusicServiceFactory.getMusicService(context)
currentDirectory.postValue(service.getVideos(refresh, context))
}
}
suspend fun getRandom(size: Int) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getRandomSongs(size, context)
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getRandomSongs(size, context)
currentDirectoryIsSortable = false
currentDirectory.postValue(musicDirectory)
}
currentDirectoryIsSortable = false
currentDirectory.postValue(musicDirectory)
}
}
suspend fun getPlaylist(playlistId: String, playlistName: String?) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getPlaylist(playlistId, playlistName, context)
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getPlaylist(playlistId, playlistName, context)
currentDirectory.postValue(musicDirectory)
}
currentDirectory.postValue(musicDirectory)
}
}
suspend fun getPodcastEpisodes(podcastChannelId: String) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getPodcastEpisodes(podcastChannelId, context)
currentDirectory.postValue(musicDirectory)
}
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = service.getPodcastEpisodes(podcastChannelId, context)
currentDirectory.postValue(musicDirectory)
}
}
suspend fun getShare(shareId: String) {
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = MusicDirectory()
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory = MusicDirectory()
val shares = service.getShares(true, context)
val shares = service.getShares(true, context)
for (share in shares) {
if (share.id == shareId) {
for (entry in share.getEntries()) {
musicDirectory.addChild(entry)
}
break
for (share in shares) {
if (share.id == shareId) {
for (entry in share.getEntries()) {
musicDirectory.addChild(entry)
}
break
}
currentDirectory.postValue(musicDirectory)
}
currentDirectory.postValue(musicDirectory)
}
}
@ -311,30 +292,28 @@ class SelectAlbumModel(application: Application) : AndroidViewModel(application)
)
withContext(Dispatchers.IO) {
if (!ActiveServerProvider.isOffline(context)) {
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory: MusicDirectory
val musicFolderId = if (showSelectFolderHeader) {
activeServerProvider.getActiveServer().musicFolderId
} else {
null
}
if (Util.getShouldUseId3Tags(context)) {
musicDirectory = service.getAlbumList2(
albumListType, size,
offset, musicFolderId, context
)
} else {
musicDirectory = service.getAlbumList(
albumListType, size,
offset, musicFolderId, context
)
}
currentDirectoryIsSortable = sortableCollection(albumListType)
albumList.postValue(musicDirectory)
val service = MusicServiceFactory.getMusicService(context)
val musicDirectory: MusicDirectory
val musicFolderId = if (showSelectFolderHeader) {
activeServerProvider.getActiveServer().musicFolderId
} else {
null
}
if (Util.getShouldUseId3Tags(context)) {
musicDirectory = service.getAlbumList2(
albumListType, size,
offset, musicFolderId, context
)
} else {
musicDirectory = service.getAlbumList(
albumListType, size,
offset, musicFolderId, context
)
}
currentDirectoryIsSortable = sortableCollection(albumListType)
albumList.postValue(musicDirectory)
}
}

View File

@ -26,7 +26,7 @@ class ApiCallResponseChecker(
if (activeServerProvider.getActiveServer().minimumApiVersion == null) {
try {
val response = subsonicAPIClient.api.ping().execute()
if (response?.body() != null) {
if (response.body() != null) {
val restApiVersion = response.body()!!.version.restApiVersion
Timber.i("Server minimum API version set to %s", restApiVersion)
activeServerProvider.setMinimumApiVersion(restApiVersion)