diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 863f91d..055df5a 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -55,7 +55,7 @@ "notInstalled": "Nije instalirano", "estimateInBrackets": "(Procjena)", "selectAll": "Označi sve", - "deselectN": "Poništi odabir {}", + "deselectX": "Poništi odabir {}", "xWillBeRemovedButRemainInstalled": "{} će biti uklonjen iz Obtainiuma, ali će ostati instaliran na uređaju.", "removeSelectedAppsQuestion": "Želite li ukloniti odabrane aplikacije?", "removeSelectedApps": "Ukloni odabrane aplikacije", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Tražim moguće nadogradnje", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/cs.json b/assets/translations/cs.json index 0ec6c30..07f5c7c 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -55,7 +55,7 @@ "notInstalled": "Není nainstalováno", "estimateInBrackets": "(přibližně)", "selectAll": "Vybrat Vše", - "deselectN": "{} deselected", + "deselectX": "{} deselected", "xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.", "removeSelectedAppsQuestion": "Odebrat vybrané aplikace?", "removeSelectedApps": "Odebrat vybrané aplikace", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Zkontrolovat aktualizace", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Odstranit Apku?", "other": "Odstranit Apky?" diff --git a/assets/translations/de.json b/assets/translations/de.json index f7ae62a..09c40c1 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -55,7 +55,7 @@ "notInstalled": "Nicht installiert", "estimateInBrackets": "(Ungefähr)", "selectAll": "Alle auswählen", - "deselectN": "{} abgewählt", + "deselectX": "{} abgewählt", "xWillBeRemovedButRemainInstalled": "{} wird aus Obtainium entfernt, bleibt aber auf dem Gerät installiert.", "removeSelectedAppsQuestion": "Ausgewählte Apps entfernen?", "removeSelectedApps": "Ausgewählte Apps entfernen", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Nach Aktualisierungen suchen", "onlyCheckInstalledOrTrackOnlyApps": "Überprüfe nur installierte und mit „nur Nachverfolgen“ markierte Apps nach Aktualisierungen", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index acff0d4..2b2349a 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -55,7 +55,7 @@ "notInstalled": "Not Installed", "estimateInBrackets": "(Estimate)", "selectAll": "Select All", - "deselectN": "Deselect {}", + "deselectX": "Deselect {}", "xWillBeRemovedButRemainInstalled": "{} will be removed from Obtainium but remain installed on device.", "removeSelectedAppsQuestion": "Remove Selected Apps?", "removeSelectedApps": "Remove Selected Apps", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Checking for Updates", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index 7792f93..a2aec10 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -55,7 +55,7 @@ "notInstalled": "No Instalado", "estimateInBrackets": "(Aproximado)", "selectAll": "Seleccionar Todo", - "deselectN": "Deseleccionar {}", + "deselectX": "Deseleccionar {}", "xWillBeRemovedButRemainInstalled": "{} será borrada de Obtainium pero continuará instalada en el dispositivo.", "removeSelectedAppsQuestion": "¿Borrar aplicaciones seleccionadas?", "removeSelectedApps": "Borrar Aplicaciones Seleccionadas", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Buscando Actualizaciones", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index a3eb511..6ff39ba 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -55,7 +55,7 @@ "notInstalled": "نصب نشده", "estimateInBrackets": "(تخمین زدن)", "selectAll": "انتخاب همه", - "deselectN": "لغو انتخاب {}", + "deselectX": "لغو انتخاب {}", "xWillBeRemovedButRemainInstalled": "{} از Obtainium حذف می‌شود اما روی دستگاه نصب می‌ماند.", "removeSelectedAppsQuestion": "برنامه های انتخابی حذف شود؟", "removeSelectedApps": "حذف برنامه های انتخاب شده", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "بررسی به‌روزرسانی‌ها", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 7b65f5d..11df6ef 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -55,7 +55,7 @@ "notInstalled": "Pas installé", "estimateInBrackets": "(Estimation)", "selectAll": "Tout sélectionner", - "deselectN": "Déselectionner {}", + "deselectX": "Déselectionner {}", "xWillBeRemovedButRemainInstalled": "{} sera supprimé d'Obtainium mais restera installé sur l'appareil.", "removeSelectedAppsQuestion": "Supprimer les applications sélectionnées ?", "removeSelectedApps": "Supprimer les applications sélectionnées", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Vérification des mises à jour", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index da95328..20f4064 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -55,7 +55,7 @@ "notInstalled": "Nem telepített", "estimateInBrackets": "(Becslés)", "selectAll": "Mindet kiválaszt", - "deselectN": "Törölje {} kijelölését", + "deselectX": "Törölje {} kijelölését", "xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.", "removeSelectedAppsQuestion": "Eltávolítja a kiválasztott appokat?", "removeSelectedApps": "Távolítsa el a kiválasztott appokat", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Frissítések keresése", "onlyCheckInstalledOrTrackOnlyApps": "Csak a telepített és a csak követhető appokat ellenőrizze frissítésekért", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" diff --git a/assets/translations/it.json b/assets/translations/it.json index 4c2eebd..93a4f10 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -55,7 +55,7 @@ "notInstalled": "Non installato", "estimateInBrackets": "(stimato)", "selectAll": "Seleziona tutto", - "deselectN": "Deseleziona {}", + "deselectX": "Deseleziona {}", "xWillBeRemovedButRemainInstalled": "Verà effettuata la rimozione di {}, ma non la disinstallazione.", "removeSelectedAppsQuestion": "Rimuovere le app selezionate?", "removeSelectedApps": "Rimuovi le app selezionate", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Controllo degli aggiornamenti in corso", "onlyCheckInstalledOrTrackOnlyApps": "Cerca aggiornamenti solo per app installate e app in Solo-Monitoraggio", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index 55a8252..fab94f8 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -55,7 +55,7 @@ "notInstalled": "未インストール", "estimateInBrackets": "(推定)", "selectAll": "すべて選択", - "deselectN": "{}件の選択を解除", + "deselectX": "{}件の選択を解除", "xWillBeRemovedButRemainInstalled": "{} はObtainiumから削除されますが、デバイスにはインストールされたままです。", "removeSelectedAppsQuestion": "選択したアプリを削除しますか?", "removeSelectedApps": "選択したアプリを削除する", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "アップデートを確認中", "onlyCheckInstalledOrTrackOnlyApps": "インストール済みのアプリと「追跡のみ」のアプリのアップデートのみを確認する", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/nl.json b/assets/translations/nl.json index 6e7c846..3d27093 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -55,7 +55,7 @@ "notInstalled": "Niet geinstalleerd", "estimateInBrackets": "(Ongeveer)", "selectAll": "Selecteer alles", - "deselectN": "Deselecteer {}", + "deselectX": "Deselecteer {}", "xWillBeRemovedButRemainInstalled": "{} zal worden verwijderd uit Obtainium, maar blijft geïnstalleerd op het apparaat.", "removeSelectedAppsQuestion": "Geselecteerde apps verwijderen??", "removeSelectedApps": "Geselecteerde apps verwijderen", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Controleren op updates", "onlyCheckInstalledOrTrackOnlyApps": "Alleen geïnstalleerde en Track-Only apps controleren op updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "App verwijderen?", "other": "Apps verwijderen?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index cd6d26f..f93ac78 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -55,7 +55,7 @@ "notInstalled": "Nie zainstalowano", "estimateInBrackets": "(Szacunkowo)", "selectAll": "Zaznacz wszystkie", - "deselectN": "Odznacz {}", + "deselectX": "Odznacz {}", "xWillBeRemovedButRemainInstalled": "{} zostanie usunięty z Obtainium, ale pozostanie zainstalowany na urządzeniu.", "removeSelectedAppsQuestion": "Usunąć wybrane aplikacje?", "removeSelectedApps": "Usuń wybrane aplikacje", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Sprawdzanie dostępności aktualizacji", "onlyCheckInstalledOrTrackOnlyApps": "Sprawdzaj tylko zainstalowane i obserwowane aplikacje pod kątem aktualizacji", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Usunąć aplikację?", "few": "Usunąć aplikacje?", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index 25345a8..6474f27 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -55,7 +55,7 @@ "notInstalled": "Não Instalado", "estimateInBrackets": "(Aproximado)", "selectAll": "Selecionar All", - "deselectN": "Deselecionar {}", + "deselectX": "Deselecionar {}", "xWillBeRemovedButRemainInstalled": "{} sera removido do Obtainium mais permanecerá instalado no dispositivo.", "removeSelectedAppsQuestion": "Remover Apps Selecionados?", "removeSelectedApps": "Remover Apps Selecionados", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Checando por Atualizações", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Remover App?", "other": "Remover Apps?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 4b91bc4..0c41983 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -55,7 +55,7 @@ "notInstalled": "Не установлено", "estimateInBrackets": "(Оценка)", "selectAll": "Выбрать всё", - "deselectN": "Отменить выбор {}", + "deselectX": "Отменить выбор {}", "xWillBeRemovedButRemainInstalled": "{} будет удалено из Obtainium, но останется на устройстве", "removeSelectedAppsQuestion": "Удалить выбранные приложения?", "removeSelectedApps": "Удалить выбранные приложения", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Проверка обновлений", "onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/sv.json b/assets/translations/sv.json index 4f680ef..6df5314 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -55,7 +55,7 @@ "notInstalled": "Inte Installerad", "estimateInBrackets": "(Uppskattning)", "selectAll": "Välj Alla", - "deselectN": "Avmarkera {}", + "deselectX": "Avmarkera {}", "xWillBeRemovedButRemainInstalled": "{} kommer tas bort från Obtainium men kommer vara fortsatt installerad på enheten.", "removeSelectedAppsQuestion": "Ta bort markerade Appar?", "removeSelectedApps": "Ta bort markerade Appar", diff --git a/assets/translations/tr.json b/assets/translations/tr.json index 724a08a..5a3c591 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -55,7 +55,7 @@ "notInstalled": "Yüklenmedi", "estimateInBrackets": "(Tahmini)", "selectAll": "Hepsini Seç", - "deselectN": "{}'yi Seçimden Kaldır", + "deselectX": "{}'yi Seçimden Kaldır", "xWillBeRemovedButRemainInstalled": "{} Obtainium'dan kaldırılacak ancak cihazınızda yüklü kalacaktır.", "removeSelectedAppsQuestion": "Seçilen Uygulamaları Kaldırmak İstiyor musunuz?", "removeSelectedApps": "Seçilen Uygulamaları Kaldır", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Güncellemeler Kontrol Ediliyor", "onlyCheckInstalledOrTrackOnlyApps": "Yalnızca yüklü ve Yalnızca İzleme Uygulamalarını güncelleme", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "Uygulamayı Kaldır?", "other": "Uygulamaları Kaldır?" diff --git a/assets/translations/vi.json b/assets/translations/vi.json index 50a78e7..f5b780a 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -55,7 +55,7 @@ "notInstalled": "Chưa cài đặt", "estimateInBrackets": "(Ước lượng)", "selectAll": "Chọn tất cả", - "deselectN": "Bỏ chọn {}", + "deselectX": "Bỏ chọn {}", "xWillBeRemovedButRemainInstalled": "{} sẽ bị xóa khỏi Obtainium nhưng vẫn còn cài đặt trên thiết bị.", "removeSelectedAppsQuestion": "Xóa ứng dụng đã chọn?", "removeSelectedApps": "Xóa ứng dụng đã chọn", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "Đang kiểm tra cập nhật", "onlyCheckInstalledOrTrackOnlyApps": "Chỉ kiểm tra các ứng dụng đã cài đặt và Chỉ-Theo dõi để biết các bản cập nhật", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion":{ "one": "Gỡ ứng dụng?", "other": "Gỡ ứng dụng?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 48dec33..b76bdfa 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -55,7 +55,7 @@ "notInstalled": "未安装", "estimateInBrackets": "(推测)", "selectAll": "全选", - "deselectN": "取消选择 {}", + "deselectX": "取消选择 {}", "xWillBeRemovedButRemainInstalled": "{} 将从 Obtainium 中删除,但仍安装在您的设备中。", "removeSelectedAppsQuestion": "是否删除选中的应用?", "removeSelectedApps": "删除选中的应用", @@ -276,6 +276,7 @@ "checkingForUpdatesNotifChannel": "正在检查更新", "onlyCheckInstalledOrTrackOnlyApps": "只对已安装和“仅追踪”的应用进行更新检查", "fixedAPKURL": "APK URL is fixed", + "selectX": "Select {}", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index c578a6e..0ff0cda 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -269,6 +269,7 @@ class _AddAppPageState extends State { context: context, builder: (BuildContext ctx) { return SelectionModal( + title: tr('selectX', args: [plural('source', 2)]), entries: sourceStrings, selectedByDefault: true, onlyOneSelectionAllowed: false, @@ -276,54 +277,56 @@ class _AddAppPageState extends State { ); }) ?? []; - var results = await Future.wait(sourceProvider.sources - .where((e) => searchSources.contains(e.name)) - .map((e) async { - try { - return await e.search(searchQuery); - } catch (err) { - if (err is! CredsNeededError) { - rethrow; - } else { - err.unexpected = true; - showError(err, context); - return >{}; + if (searchSources.isNotEmpty) { + var results = await Future.wait(sourceProvider.sources + .where((e) => searchSources.contains(e.name)) + .map((e) async { + try { + return await e.search(searchQuery); + } catch (err) { + if (err is! CredsNeededError) { + rethrow; + } else { + err.unexpected = true; + showError(err, context); + return >{}; + } } - } - })); + })); - // .then((results) async { - // Interleave results instead of simple reduce - Map> res = {}; - var si = 0; - var done = false; - while (!done) { - done = true; - for (var r in results) { - if (r.length > si) { - done = false; - res.addEntries([r.entries.elementAt(si)]); + // .then((results) async { + // Interleave results instead of simple reduce + Map> res = {}; + var si = 0; + var done = false; + while (!done) { + done = true; + for (var r in results) { + if (r.length > si) { + done = false; + res.addEntries([r.entries.elementAt(si)]); + } } + si++; + } + if (res.isEmpty) { + throw ObtainiumError(tr('noResults')); + } + List? selectedUrls = res.isEmpty + ? [] + // ignore: use_build_context_synchronously + : await showDialog?>( + context: context, + builder: (BuildContext ctx) { + return SelectionModal( + entries: res, + selectedByDefault: false, + onlyOneSelectionAllowed: true, + ); + }); + if (selectedUrls != null && selectedUrls.isNotEmpty) { + changeUserInput(selectedUrls[0], true, false, isSearch: true); } - si++; - } - if (res.isEmpty) { - throw ObtainiumError(tr('noResults')); - } - List? selectedUrls = res.isEmpty - ? [] - // ignore: use_build_context_synchronously - : await showDialog?>( - context: context, - builder: (BuildContext ctx) { - return SelectionModal( - entries: res, - selectedByDefault: false, - onlyOneSelectionAllowed: true, - ); - }); - if (selectedUrls != null && selectedUrls.isNotEmpty) { - changeUserInput(selectedUrls[0], true, false, isSearch: true); } } catch (e) { showError(e, context); diff --git a/lib/pages/import_export.dart b/lib/pages/import_export.dart index 032180f..db777a7 100644 --- a/lib/pages/import_export.dart +++ b/lib/pages/import_export.dart @@ -428,6 +428,11 @@ class _ImportExportPageState extends State { (BuildContext ctx) { return SelectionModal( + title: tr( + 'selectX', + args: [ + tr('source') + ]), entries: sourceStrings, selectedByDefault: @@ -565,8 +570,10 @@ class SelectionModal extends StatefulWidget { required this.entries, this.selectedByDefault = true, this.onlyOneSelectionAllowed = false, - this.titlesAreLinks = true}); + this.titlesAreLinks = true, + this.title}); + String? title; Map> entries; bool selectedByDefault; bool onlyOneSelectionAllowed; @@ -600,7 +607,7 @@ class _SelectionModalState extends State { Widget build(BuildContext context) { return AlertDialog( scrollable: true, - title: Text(tr('select')), + title: Text(widget.title ?? tr('pick')), content: Column(children: [ ...entrySelections.keys.map((entry) { selectThis(bool? value) { @@ -701,8 +708,8 @@ class _SelectionModalState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - height: entry.value.length <= 1 ? 16 : 8, + const SizedBox( + height: 8, ), GestureDetector( onTap: widget.titlesAreLinks @@ -720,11 +727,9 @@ class _SelectionModalState extends State { }, child: descriptionText, ), - entry.value.length <= 1 - ? const SizedBox.shrink() - : const SizedBox( - height: 8, - ) + const SizedBox( + height: 8, + ) ], )) ]); @@ -751,8 +756,8 @@ class _SelectionModalState extends State { }, child: Text(widget.onlyOneSelectionAllowed ? tr('pick') - : tr('importX', args: [ - plural('url', entrySelections.values.where((b) => b).length) + : tr('selectX', args: [ + entrySelections.values.where((b) => b).length.toString() ]))) ], );