diff --git a/assets/translations/bs.json b/assets/translations/bs.json index 2c3c5d3..ef08037 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "Sort by file names instead of full links", "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "customLinkFilterRegex": "Custom Link Filter by Regular Expression (Default '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} i još 1 aplikacija je ažurirana.", "other": "{} i još {} aplikacija je ažurirano." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/de.json b/assets/translations/de.json index b47e385..ffc08dc 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "Sortiere nach Dateinamen, anstelle von ganzen Links", "filterReleaseNotesByRegEx": "Versionshinweise nach regulärem Ausdruck filtern", "customLinkFilterRegex": "Benutzerdefinierter Link Filter nach Regulärem Ausdruck (Standard '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} und 1 weitere Anwendung wurden aktualisiert.", "other": "{} und {} weitere Anwendungen wurden aktualisiert." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/en.json b/assets/translations/en.json index 397c7a2..8fa9763 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "Sort by file names instead of full links", "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "customLinkFilterRegex": "Custom Link Filter by Regular Expression (Default '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} and 1 more app were updated.", "other": "{} and {} more apps were updated." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/es.json b/assets/translations/es.json index b5d3d25..bffc0de 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "Sort by file names instead of full links", "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "customLinkFilterRegex": "Custom Link Filter by Regular Expression (Default '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} y 1 aplicación más han sido actualizadas.", "other": "{} y {} aplicaciones más han sido actualizadas." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 3f98e69..02027bf 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "مرتب سازی بر اساس نام فایل به جای پیوندهای کامل", "filterReleaseNotesByRegEx": "یادداشت های انتشار را با بیان منظم فیلتر کنید", "customLinkFilterRegex": "فیلتر پیوند سفارشی بر اساس عبارت منظم (پیش‌فرض '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} و 1 برنامه دیگر به روز شدند.", "other": "{} و {} برنامه دیگر به روز شدند." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/fr.json b/assets/translations/fr.json index ec680f8..582e286 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "Sort by file names instead of full links", "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "customLinkFilterRegex": "Custom Link Filter by Regular Expression (Default '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} et 1 autre application ont été mises à jour.", "other": "{} et {} autres applications ont été mises à jour." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/hu.json b/assets/translations/hu.json index da0b17a..5164bcd 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -246,6 +246,9 @@ "sortByFileNamesNotLinks": "Fájlnevek szerinti elrendezés teljes linkek helyett", "filterReleaseNotesByRegEx": "Kiadási megjegyzések szűrése reguláris kifejezéssel", "customLinkFilterRegex": "Custom Link Filter by Regular Expression (Default '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" @@ -293,5 +296,9 @@ "xAndNMoreUpdatesInstalled": { "one": "A(z) {} és 1 további alkalmazás frissítve.", "other": "{} és {} további alkalmazás frissítve." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/it.json b/assets/translations/it.json index 4dd0383..ed43216 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "Sort by file names instead of full links", "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "customLinkFilterRegex": "Custom Link Filter by Regular Expression (Default '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} e un'altra app sono state aggiornate.", "other": "{} e altre {} app sono state aggiornate." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/ja.json b/assets/translations/ja.json index 1ade9f2..37edc58 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "フルのリンクではなくファイル名でソートする", "filterReleaseNotesByRegEx": "正規表現でリリースノートをフィルタリングする", "customLinkFilterRegex": "正規表現によるカスタムリンクフィルター (デフォルト '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} とさらに {} 個のアプリがアップデートされました", "other": "{} とさらに {} 個のアプリがアップデートされました" + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/pl.json b/assets/translations/pl.json index b8a1a81..ea8be8a 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -251,6 +251,9 @@ "sortByFileNamesNotLinks": "Sortuj wg nazw plików zamiast pełnych linków", "filterReleaseNotesByRegEx": "Filtruj informacje o wersji według wyrażenia regularnego", "customLinkFilterRegex": "Niestandardowy filtr linków wg. wyrażenia regularnego (domyślnie \".apk$\")", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "Usunąć aplikację?", "other": "Usunąć aplikacje?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "Zaktualizowano {} i jeszcze 1 aplikację.", "other": "Zaktualizowano {} i {} aplik." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 1f27453..609b5e3 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "Sort by file names instead of full links", "filterReleaseNotesByRegEx": "Filter Release Notes by Regular Expression", "customLinkFilterRegex": "Custom Link Filter by Regular Expression (Default '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} и еще 1 приложение были обновлены.", "other": "{} и еще {} приложений были обновлены." + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 028e8d1..1aa36fc 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -247,6 +247,9 @@ "sortByFileNamesNotLinks": "根据文件名而不是完整链接来排序", "filterReleaseNotesByRegEx": "用正则表达式筛选发布说明", "customLinkFilterRegex": "用正则表达式自定义链接筛选(默认 '.apk$')", + "appsPossiblyUpdated": "App Updates Attempted", + "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", + "xWasPossiblyUpdatedToY": "An attempt was made to update {} to {}.", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" @@ -294,5 +297,9 @@ "xAndNMoreUpdatesInstalled": { "one": "{} 和另外 1 个应用已更新。", "other": "{} 和另外 {} 个应用已更新。" + }, + "xAndNMoreUpdatesPossiblyInstalled": { + "one": "Attempts were made to update {} and 1 more app.", + "other": "Attempts were made to update {} and {} more apps." } } diff --git a/lib/main.dart b/lib/main.dart index 5074433..79bdfcb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -88,10 +88,8 @@ Future bgUpdateCheck(int taskId, Map? params) async { : null; logs.add(tr('bgUpdateIgnoreAfterIs', args: [ignoreAfter.toString()])); var notificationsProvider = NotificationsProvider(); - await notificationsProvider.notify(checkingUpdatesNotification); try { var appsProvider = AppsProvider(); - await notificationsProvider.cancel(ErrorCheckingUpdatesNotification('').id); await appsProvider.loadApps(); List existingUpdateIds = appsProvider.findExistingUpdates(installedOnly: true); @@ -100,7 +98,9 @@ Future bgUpdateCheck(int taskId, Map? params) async { try { logs.add(tr('startedActualBGUpdateCheck')); await appsProvider.checkUpdates( - ignoreAppsCheckedAfter: ignoreAfter, throwErrorsForRetry: true); + ignoreAppsCheckedAfter: ignoreAfter, + throwErrorsForRetry: true, + notificationsProvider: notificationsProvider); } catch (e) { if (e is RateLimitError || e is ClientException) { var remainingMinutes = e is RateLimitError ? e.remainingMinutes : 15; @@ -124,34 +124,29 @@ Future bgUpdateCheck(int taskId, Map? params) async { .where((id) => !existingUpdateIds.contains(id)) .map((e) => appsProvider.apps[e]!.app) .toList(); - - // TODO: This silent update code doesn't work yet - // List silentlyUpdated = await appsProvider - // .downloadAndInstallLatestApp( - // [...newUpdates.map((e) => e.id), ...existingUpdateIds], null); - // if (silentlyUpdated.isNotEmpty) { - // newUpdates = newUpdates - // .where((element) => !silentlyUpdated.contains(element.id)) - // .toList(); - // notificationsProvider.notify( - // SilentUpdateNotification( - // silentlyUpdated.map((e) => appsProvider.apps[e]!.app).toList()), - // cancelExisting: true); - // } - logs.add( - plural('bgCheckFoundUpdatesWillNotifyIfNeeded', newUpdates.length)); - if (newUpdates.isNotEmpty) { - notificationsProvider.notify(UpdateNotification(newUpdates)); + List nonSilentUpdates = []; + List silentUpdates = []; + for (var a in newUpdates) { + if (await appsProvider.canInstallSilently(a)) { + silentUpdates.add(a); + } else { + nonSilentUpdates.add(a); + } } + if (silentUpdates.isNotEmpty) { + await appsProvider.downloadAndInstallLatestApps( + silentUpdates.map((e) => e.id).toList(), null, + notificationsProvider: notificationsProvider); + } + logs.add(plural( + 'bgCheckFoundUpdatesWillNotifyIfNeeded', nonSilentUpdates.length)); if (err != null) { throw err; } } catch (e) { - notificationsProvider - .notify(ErrorCheckingUpdatesNotification(e.toString())); + logs.add('${tr('errorCheckingUpdates')}: ${e.toString()}'); } finally { logs.add(tr('bgUpdateTaskFinished')); - await notificationsProvider.cancel(checkingUpdatesNotification.id); } } diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 3c63a72..30f75bd 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -239,9 +239,8 @@ class AppsProvider with ChangeNotifier { return downloadedFile; } - Future downloadApp(App app, BuildContext? context) async { - NotificationsProvider? notificationsProvider = - context?.read(); + Future downloadApp(App app, BuildContext? context, + {NotificationsProvider? notificationsProvider}) async { var notifId = DownloadNotification(app.finalName, 0).id; if (apps[app.id] != null) { apps[app.id]!.downloadProgress = 0; @@ -507,7 +506,10 @@ class AppsProvider with ChangeNotifier { // Returns an array of Ids for Apps that were successfully downloaded, regardless of installation result Future> downloadAndInstallLatestApps( List appIds, BuildContext? context, - {SettingsProvider? settingsProvider}) async { + {SettingsProvider? settingsProvider, + NotificationsProvider? notificationsProvider}) async { + notificationsProvider = + notificationsProvider ?? context?.read(); List appsToInstall = []; List trackOnlyAppsToUpdate = []; // For all specified Apps, filter out those for which: @@ -567,8 +569,10 @@ class AppsProvider with ChangeNotifier { for (var id in appsToInstall) { try { - // ignore: use_build_context_synchronously - var downloadedArtifact = await downloadApp(apps[id]!.app, context); + var downloadedArtifact = + // ignore: use_build_context_synchronously + await downloadApp(apps[id]!.app, context, + notificationsProvider: notificationsProvider); DownloadedApk? downloadedFile; DownloadedXApkDir? downloadedDir; if (downloadedArtifact is DownloadedApk) { @@ -576,8 +580,8 @@ class AppsProvider with ChangeNotifier { } else { downloadedDir = downloadedArtifact as DownloadedXApkDir; } - bool willBeSilent = await canInstallSilently( - apps[downloadedFile?.appId ?? downloadedDir!.appId]!.app); + var appId = downloadedFile?.appId ?? downloadedDir!.appId; + bool willBeSilent = await canInstallSilently(apps[appId]!.app); if (!(await settingsProvider?.getInstallPermission(enforce: false) ?? true)) { throw ObtainiumError(tr('cancelled')); @@ -590,9 +594,24 @@ class AppsProvider with ChangeNotifier { notifyListeners(); try { if (downloadedFile != null) { - await installApk(downloadedFile); + if (willBeSilent) { + // Would await forever - workaround - TODO + installApk(downloadedFile); + } else { + await installApk(downloadedFile); + } } else { - await installXApkDir(downloadedDir!); + if (willBeSilent) { + // Would await forever - workaround - TODO + installXApkDir(downloadedDir!); + } else { + await installXApkDir(downloadedDir!); + } + } + if (willBeSilent) { + notificationsProvider?.notify(SilentUpdateAttemptNotification( + [apps[appId]!.app], + id: appId.hashCode)); } } finally { apps[id]?.downloadProgress = null; @@ -608,8 +627,6 @@ class AppsProvider with ChangeNotifier { throw errors; } - NotificationsProvider().cancel(UpdateNotification([]).id); - return installedIds; } @@ -971,7 +988,8 @@ class AppsProvider with ChangeNotifier { Future> checkUpdates( {DateTime? ignoreAppsCheckedAfter, - bool throwErrorsForRetry = false}) async { + bool throwErrorsForRetry = false, + NotificationsProvider? notificationsProvider}) async { List updates = []; MultiAppMultiError errors = MultiAppMultiError(); if (!gettingUpdates) { @@ -998,9 +1016,14 @@ class AppsProvider with ChangeNotifier { rethrow; } errors.add(appIds[i], e.toString()); + notificationsProvider?.notify(ErrorCheckingUpdatesNotification( + '${appIds[i]}: ${e.toString()}', + id: appIds[i].hashCode)); } if (newApp != null) { updates.add(newApp); + notificationsProvider + ?.notify(UpdateNotification([newApp], id: newApp.id.hashCode)); } } } finally { diff --git a/lib/providers/notifications_provider.dart b/lib/providers/notifications_provider.dart index 1f39cc8..1c2ab23 100644 --- a/lib/providers/notifications_provider.dart +++ b/lib/providers/notifications_provider.dart @@ -22,9 +22,9 @@ class ObtainiumNotification { } class UpdateNotification extends ObtainiumNotification { - UpdateNotification(List updates) + UpdateNotification(List updates, {int? id}) : super( - 2, + id ?? 2, tr('updatesAvailable'), '', 'UPDATES_AVAILABLE', @@ -41,8 +41,8 @@ class UpdateNotification extends ObtainiumNotification { } class SilentUpdateNotification extends ObtainiumNotification { - SilentUpdateNotification(List updates) - : super(3, tr('appsUpdated'), '', 'APPS_UPDATED', tr('appsUpdated'), + SilentUpdateNotification(List updates, {int? id}) + : super(id ?? 3, tr('appsUpdated'), '', 'APPS_UPDATED', tr('appsUpdated'), tr('appsUpdatedNotifDescription'), Importance.defaultImportance) { message = updates.length == 1 ? tr('xWasUpdatedToY', @@ -52,10 +52,28 @@ class SilentUpdateNotification extends ObtainiumNotification { } } -class ErrorCheckingUpdatesNotification extends ObtainiumNotification { - ErrorCheckingUpdatesNotification(String error) +class SilentUpdateAttemptNotification extends ObtainiumNotification { + SilentUpdateAttemptNotification(List updates, {int? id}) : super( - 5, + id ?? 3, + tr('appsPossiblyUpdated'), + '', + 'APPS_POSSIBLY_UPDATED', + tr('appsPossiblyUpdated'), + tr('appsPossiblyUpdatedNotifDescription'), + Importance.defaultImportance) { + message = updates.length == 1 + ? tr('xWasPossiblyUpdatedToY', + args: [updates[0].finalName, updates[0].latestVersion]) + : plural('xAndNMoreUpdatesPossiblyInstalled', updates.length - 1, + args: [updates[0].finalName, (updates.length - 1).toString()]); + } +} + +class ErrorCheckingUpdatesNotification extends ObtainiumNotification { + ErrorCheckingUpdatesNotification(String error, {int? id}) + : super( + id ?? 5, tr('errorCheckingUpdates'), error, 'BG_UPDATE_CHECK_ERROR',