diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/util/Util.java b/ultrasonic/src/main/java/org/moire/ultrasonic/util/Util.java index f89ed103..82366ed6 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/util/Util.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/util/Util.java @@ -594,16 +594,16 @@ public class Util } - private static void showDialog(Context context, int icon, int titleId, int messageId) + // The AlertDialog requires an Activity context, app context is not enough + // See https://stackoverflow.com/questions/5436822/ + public static void showDialog(Context context, int icon, int titleId, String message) { - new AlertDialog.Builder(context).setIcon(icon).setTitle(titleId).setMessage(messageId).setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() - { - @Override - public void onClick(DialogInterface dialog, int i) - { - dialog.dismiss(); - } - }).show(); + new AlertDialog.Builder(context) + .setIcon(icon) + .setTitle(titleId) + .setMessage(message) + .setPositiveButton(R.string.common_ok, (dialog, i) -> dialog.dismiss()) + .show(); } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt index 54f88c30..7f8abc29 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -29,7 +29,9 @@ import androidx.preference.PreferenceManager import com.google.android.material.navigation.NavigationView import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.java.KoinJavaComponent.inject import org.moire.ultrasonic.R +import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline import org.moire.ultrasonic.domain.PlayerState import org.moire.ultrasonic.fragment.OnBackPressedHandler @@ -368,10 +370,18 @@ class NavigationActivity : AppCompatActivity() { } private fun setMenuForServerSetting() { - val visibility = !isOffline() - chatMenuItem?.isVisible = visibility - bookmarksMenuItem?.isVisible = visibility - sharesMenuItem?.isVisible = visibility - podcastsMenuItem?.isVisible = visibility + if (isOffline()) { + chatMenuItem?.isVisible = false + bookmarksMenuItem?.isVisible = false + sharesMenuItem?.isVisible = false + podcastsMenuItem?.isVisible = false + return + } + val activeServerProvider: ActiveServerProvider by inject() + val activeServer = activeServerProvider.getActiveServer() + chatMenuItem?.isVisible = activeServer.chatSupport != false + bookmarksMenuItem?.isVisible = activeServer.bookmarkSupport != false + sharesMenuItem?.isVisible = activeServer.shareSupport != false + podcastsMenuItem?.isVisible = activeServer.podcastSupport != false } } 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 ee265000..e4aa77dc 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt @@ -8,7 +8,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase /** * Room Database to be used to store data for Ultrasonic */ -@Database(entities = [ServerSetting::class], version = 2) +@Database(entities = [ServerSetting::class], version = 3) abstract class AppDatabase : RoomDatabase() { /** @@ -24,3 +24,20 @@ val MIGRATION_1_2: Migration = object : Migration(1, 2) { ) } } + +val MIGRATION_2_3: Migration = object : Migration(2, 3) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + "ALTER TABLE ServerSetting ADD COLUMN chatSupport INTEGER" + ) + database.execSQL( + "ALTER TABLE ServerSetting ADD COLUMN bookmarkSupport INTEGER" + ) + database.execSQL( + "ALTER TABLE ServerSetting ADD COLUMN shareSupport INTEGER" + ) + database.execSQL( + "ALTER TABLE ServerSetting ADD COLUMN podcastSupport INTEGER" + ) + } +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt index c5749a23..705f526a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt @@ -29,7 +29,11 @@ data class ServerSetting( @ColumnInfo(name = "allowSelfSignedCertificate") var allowSelfSignedCertificate: Boolean, @ColumnInfo(name = "ldapSupport") var ldapSupport: Boolean, @ColumnInfo(name = "musicFolderId") var musicFolderId: String?, - @ColumnInfo(name = "minimumApiVersion") var minimumApiVersion: String? + @ColumnInfo(name = "minimumApiVersion") var minimumApiVersion: String?, + @ColumnInfo(name = "chatSupport") var chatSupport: Boolean? = null, + @ColumnInfo(name = "bookmarkSupport") var bookmarkSupport: Boolean? = null, + @ColumnInfo(name = "shareSupport") var shareSupport: Boolean? = null, + @ColumnInfo(name = "podcastSupport") var podcastSupport: Boolean? = null ) { constructor() : this ( -1, 0, "", "", "", "", false, false, false, null, null 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 e92454b4..1b430ae1 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt @@ -7,6 +7,7 @@ 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_3 import org.moire.ultrasonic.fragment.ServerSettingsModel import org.moire.ultrasonic.util.Util @@ -25,6 +26,7 @@ val appPermanentStorage = module { "ultrasonic-database" ) .addMigrations(MIGRATION_1_2) + .addMigrations(MIGRATION_2_3) .fallbackToDestructiveMigrationOnDowngrade() .build() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt index 1647fdeb..39dc892d 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt @@ -11,8 +11,10 @@ import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import com.google.android.material.switchmaterial.SwitchMaterial import com.google.android.material.textfield.TextInputLayout +import java.io.IOException import java.net.MalformedURLException import java.net.URL +import java.util.Locale import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel import org.moire.ultrasonic.BuildConfig @@ -20,14 +22,17 @@ import org.moire.ultrasonic.R import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration +import org.moire.ultrasonic.api.subsonic.response.SubsonicResponse import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ServerSetting import org.moire.ultrasonic.service.ApiCallResponseChecker import org.moire.ultrasonic.service.MusicServiceFactory +import org.moire.ultrasonic.service.SubsonicRESTException import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.ErrorDialog import org.moire.ultrasonic.util.ModalBackgroundTask import org.moire.ultrasonic.util.Util +import retrofit2.Response import timber.log.Timber /** @@ -295,14 +300,41 @@ class EditServerFragment : Fragment(), OnBackPressedHandler { * Tests if the network connection to the entered Server Settings can be made */ private fun testConnection() { - val task: ModalBackgroundTask = object : ModalBackgroundTask( + val task: ModalBackgroundTask = object : ModalBackgroundTask( activity, false ) { + fun boolToMark(value: Boolean?): String { + if (value == null) + return "⌛" + return if (value) "✔️" else "❌" + } + + fun getProgress(): String { + return String.format( + """ + |%s - ${resources.getString(R.string.button_bar_chat)} + |%s - ${resources.getString(R.string.button_bar_bookmarks)} + |%s - ${resources.getString(R.string.button_bar_shares)} + |%s - ${resources.getString(R.string.button_bar_podcasts)} + """.trimMargin(), + boolToMark(currentServerSetting!!.chatSupport), + boolToMark(currentServerSetting!!.bookmarkSupport), + boolToMark(currentServerSetting!!.shareSupport), + boolToMark(currentServerSetting!!.podcastSupport) + ) + } @Throws(Throwable::class) - override fun doInBackground(): Boolean { - updateProgress(R.string.settings_testing_connection) + override fun doInBackground(): String { + + currentServerSetting!!.chatSupport = null + currentServerSetting!!.bookmarkSupport = null + currentServerSetting!!.shareSupport = null + currentServerSetting!!.podcastSupport = null + + updateProgress(getProgress()) + val configuration = SubsonicClientConfiguration( currentServerSetting!!.url, currentServerSetting!!.userName, @@ -330,17 +362,62 @@ class EditServerFragment : Fragment(), OnBackPressedHandler { pingResponse = subsonicApiClient.api.ping().execute() ApiCallResponseChecker.checkResponseSuccessful(pingResponse) + currentServerSetting!!.chatSupport = isServerFunctionAvailable { + subsonicApiClient.api.getChatMessages().execute() + } + + updateProgress(getProgress()) + + currentServerSetting!!.bookmarkSupport = isServerFunctionAvailable { + subsonicApiClient.api.getBookmarks().execute() + } + + updateProgress(getProgress()) + + currentServerSetting!!.shareSupport = isServerFunctionAvailable { + subsonicApiClient.api.getShares().execute() + } + + updateProgress(getProgress()) + + currentServerSetting!!.podcastSupport = isServerFunctionAvailable { + subsonicApiClient.api.getPodcasts().execute() + } + + updateProgress(getProgress()) + val licenseResponse = subsonicApiClient.api.getLicense().execute() ApiCallResponseChecker.checkResponseSuccessful(licenseResponse) - return licenseResponse.body()!!.license.valid + if (!licenseResponse.body()!!.license.valid) { + return getProgress() + "\n" + + resources.getString(R.string.settings_testing_unlicensed) + } + return getProgress() } - override fun done(licenseValid: Boolean) { - if (licenseValid) { - Util.toast(activity, R.string.settings_testing_ok) - } else { - Util.toast(activity, R.string.settings_testing_unlicensed) + override fun done(responseString: String) { + var dialogText = responseString + if (arrayOf( + currentServerSetting!!.chatSupport, + currentServerSetting!!.bookmarkSupport, + currentServerSetting!!.shareSupport, + currentServerSetting!!.podcastSupport + ).any { x -> x == false } + ) { + dialogText = String.format( + Locale.ROOT, + "%s\n\n%s", + responseString, + resources.getString(R.string.server_editor_disabled_feature) + ) } + + Util.showDialog( + activity, + android.R.drawable.ic_dialog_info, + R.string.settings_testing_ok, + dialogText + ) } override fun error(error: Throwable) { @@ -359,6 +436,18 @@ class EditServerFragment : Fragment(), OnBackPressedHandler { task.execute() } + private fun isServerFunctionAvailable(function: () -> Response): Boolean { + return try { + val response = function() + ApiCallResponseChecker.checkResponseSuccessful(response) + true + } catch (_: IOException) { + false + } catch (_: SubsonicRESTException) { + false + } + } + /** * Finishes the Activity, after confirmation from the user if needed */ diff --git a/ultrasonic/src/main/res/values-cs/strings.xml b/ultrasonic/src/main/res/values-cs/strings.xml index eae638c6..21c58346 100644 --- a/ultrasonic/src/main/res/values-cs/strings.xml +++ b/ultrasonic/src/main/res/values-cs/strings.xml @@ -297,7 +297,6 @@ Zobrazovat číslo skladby Připojovat číslo skladby při zobrazování skladby Test připojení - Testuji připojení… Připojení je v pořádku Připojení je v pořádku. Server bez licence. Světlý diff --git a/ultrasonic/src/main/res/values-de/strings.xml b/ultrasonic/src/main/res/values-de/strings.xml index 32b362a5..ee0c65bf 100644 --- a/ultrasonic/src/main/res/values-de/strings.xml +++ b/ultrasonic/src/main/res/values-de/strings.xml @@ -296,7 +296,6 @@ Titelnummer anzeigen Titel mit Nummer anzeigen Verbindung testen - Teste Verbindung… Verbindung OK Verbindung OK, Server nicht lizensiert. Hell diff --git a/ultrasonic/src/main/res/values-es/strings.xml b/ultrasonic/src/main/res/values-es/strings.xml index 5c2520ba..6b11208a 100644 --- a/ultrasonic/src/main/res/values-es/strings.xml +++ b/ultrasonic/src/main/res/values-es/strings.xml @@ -309,7 +309,6 @@ Mostrar número de pista Incluir el número de pista cuando se muestre una canción Comprobar conexión - Comprobado conexión… La conexión es correcta La conexión es correcta. Servidor sin licencia. Claro diff --git a/ultrasonic/src/main/res/values-fr/strings.xml b/ultrasonic/src/main/res/values-fr/strings.xml index f2f65ed8..7270a666 100644 --- a/ultrasonic/src/main/res/values-fr/strings.xml +++ b/ultrasonic/src/main/res/values-fr/strings.xml @@ -297,7 +297,6 @@ Afficher le numéro du titre Inclure son numero lors de l\'affichage d\'un titre Tester la connexion - Connexion en cours de test… Connexion correcte Connexion correcte. Serveur sans licence. Clair @@ -499,5 +498,6 @@ Utiliser un système de notation à base d\'étoiles pour les morceaux au lieu de simplement mettre en avant les morceaux. + Une ou plusieurs fonctionnalités ont été désactivées car le serveur ne les prend pas en charge.\nVous pouvez réexécuter ce test à tout moment. diff --git a/ultrasonic/src/main/res/values-hu/strings.xml b/ultrasonic/src/main/res/values-hu/strings.xml index c185bcf5..3999ff01 100644 --- a/ultrasonic/src/main/res/values-hu/strings.xml +++ b/ultrasonic/src/main/res/values-hu/strings.xml @@ -297,7 +297,6 @@ Sorszám megjelenítése Dalok sorszámának megjelenítése. Kapcsolat tesztelése - Kapcsolat tesztelése… Kapcsolat OK! Kapcsolat OK! A kiszolgálónak nincs licence! Világos diff --git a/ultrasonic/src/main/res/values-it/strings.xml b/ultrasonic/src/main/res/values-it/strings.xml index a74532b5..043368a8 100644 --- a/ultrasonic/src/main/res/values-it/strings.xml +++ b/ultrasonic/src/main/res/values-it/strings.xml @@ -289,7 +289,6 @@ Visualizza numero traccia Includi numero traccia quando visualizzi una canzone Prova Connessione - Collaudo connessione… Connessione OK Connessione OK. Server senza licenza. Chiaro diff --git a/ultrasonic/src/main/res/values-nl/strings.xml b/ultrasonic/src/main/res/values-nl/strings.xml index 41c77857..d39fd5fd 100644 --- a/ultrasonic/src/main/res/values-nl/strings.xml +++ b/ultrasonic/src/main/res/values-nl/strings.xml @@ -307,7 +307,6 @@ Itemnummer tonen Itemnummer tonen tijdens tonen van nummers Verbinding testen - Bezig met testen van verbinding… Verbinding is goed Verbinding is goed; geen serverlicentie. Licht diff --git a/ultrasonic/src/main/res/values-pl/strings.xml b/ultrasonic/src/main/res/values-pl/strings.xml index 12d063bb..c09b4479 100644 --- a/ultrasonic/src/main/res/values-pl/strings.xml +++ b/ultrasonic/src/main/res/values-pl/strings.xml @@ -295,7 +295,6 @@ Wyświetlaj numer utworu Dołącza numer utworu podczas wyświetlania utworu Testuj połączenie - Trwa testowanie połączenia… Połączenie jest OK Połączenie jest OK. Brak licencji na serwerze. Jasny diff --git a/ultrasonic/src/main/res/values-pt-rBR/strings.xml b/ultrasonic/src/main/res/values-pt-rBR/strings.xml index 9989f711..0a864f66 100644 --- a/ultrasonic/src/main/res/values-pt-rBR/strings.xml +++ b/ultrasonic/src/main/res/values-pt-rBR/strings.xml @@ -297,7 +297,6 @@ Mostrar o Número da Faixa Incluir o número da faixa quando mostrando uma música Teste de Conexão - Testando conexão… Conexão OK Conexão OK. Servidor não licenciado. Claro diff --git a/ultrasonic/src/main/res/values-pt/strings.xml b/ultrasonic/src/main/res/values-pt/strings.xml index d607c8c4..74a7d3d4 100644 --- a/ultrasonic/src/main/res/values-pt/strings.xml +++ b/ultrasonic/src/main/res/values-pt/strings.xml @@ -295,7 +295,6 @@ Mostrar o Número da Faixa Incluir o número da faixa quando mostrando uma música Teste de Conexão - Testando conexão… Conexão OK Conexão OK. Servidor não licenciado. Claro diff --git a/ultrasonic/src/main/res/values-ru/strings.xml b/ultrasonic/src/main/res/values-ru/strings.xml index 277f7d6b..76d8f0c0 100644 --- a/ultrasonic/src/main/res/values-ru/strings.xml +++ b/ultrasonic/src/main/res/values-ru/strings.xml @@ -290,7 +290,6 @@ Показать номер трека Включить номер дорожки при отображении песни Тестовое соединение - Тестирование соединения… Успешное соединение Успешное соединение. Сервер нелицензионный. Светлая diff --git a/ultrasonic/src/main/res/values-zh-rCN/strings.xml b/ultrasonic/src/main/res/values-zh-rCN/strings.xml index 9ebc2ebc..e6fd90bf 100644 --- a/ultrasonic/src/main/res/values-zh-rCN/strings.xml +++ b/ultrasonic/src/main/res/values-zh-rCN/strings.xml @@ -220,7 +220,6 @@ 显示通知 总是显示通知 测试连接 - 测试连接… 连接正常 连接正常, 服务器未授权。 主题 diff --git a/ultrasonic/src/main/res/values/strings.xml b/ultrasonic/src/main/res/values/strings.xml index 7ab179e0..f0733e73 100644 --- a/ultrasonic/src/main/res/values/strings.xml +++ b/ultrasonic/src/main/res/values/strings.xml @@ -311,7 +311,6 @@ Show Track Number Include track number when displaying a song Test Connection - Testing connection… Connection is OK Connection is OK. Server unlicensed. Light @@ -462,6 +461,7 @@ Move down Authentication Advanced settings + One or more features were disabled because the server doesn\'t support them.\nYou can run this test again anytime. 1 song