mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-22 18:33:45 +02:00 
			
		
		
		
	Merge pull request #1161 from ImranR98/dev
- Custom link support (#368, #918) - Export settings (#1157) - Use public GitLab search API (#1147) - Fix unauthorized error (#1153)
This commit is contained in:
		| @@ -30,6 +30,13 @@ | |||||||
|                     android:name="com.android_package_installer.content.SESSION_API_PACKAGE_INSTALLED" |                     android:name="com.android_package_installer.content.SESSION_API_PACKAGE_INSTALLED" | ||||||
|                     android:exported="false" /> |                     android:exported="false" /> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|  |             <intent-filter> | ||||||
|  |                 <action android:name="android.intent.action.VIEW" /> | ||||||
|  |                 <category android:name="android.intent.category.DEFAULT" /> | ||||||
|  |                 <category android:name="android.intent.category.BROWSABLE" /> | ||||||
|  |                 <data android:scheme="obtainium" /> | ||||||
|  |             </intent-filter> | ||||||
|  |  | ||||||
|         </activity> |         </activity> | ||||||
|         <!-- Don't delete the meta-data below. |         <!-- Don't delete the meta-data below. | ||||||
|              This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |              This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Istaknite manje vidljive touch mete", |     "highlightTouchTargets": "Istaknite manje vidljive touch mete", | ||||||
|     "pickExportDir": "Izaberite datoteku za izvoz", |     "pickExportDir": "Izaberite datoteku za izvoz", | ||||||
|     "autoExportOnChanges": "Automatski izvezite pri promjenama", |     "autoExportOnChanges": "Automatski izvezite pri promjenama", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filtrirajte verzije po regulatnom izrazu", |     "filterVersionsByRegEx": "Filtrirajte verzije po regulatnom izrazu", | ||||||
|     "trySelectingSuggestedVersionCode": "Probajte izabrati preloženu (verziju) versionCode APK-a", |     "trySelectingSuggestedVersionCode": "Probajte izabrati preloženu (verziju) versionCode APK-a", | ||||||
|     "dontSortReleasesList": "Zadrži redosled izdanja iz API-a", |     "dontSortReleasesList": "Zadrži redosled izdanja iz API-a", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Zvýraznit méně zjevné cíle dotyku", |     "highlightTouchTargets": "Zvýraznit méně zjevné cíle dotyku", | ||||||
|     "pickExportDir": "Vybrat adresář pro export", |     "pickExportDir": "Vybrat adresář pro export", | ||||||
|     "autoExportOnChanges": "Automatický export při změnách", |     "autoExportOnChanges": "Automatický export při změnách", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filtrovat verze podle regulárního výrazu", |     "filterVersionsByRegEx": "Filtrovat verze podle regulárního výrazu", | ||||||
|     "trySelectingSuggestedVersionCode": "Zkusit vybrat navrhovaný kód verze APK", |     "trySelectingSuggestedVersionCode": "Zkusit vybrat navrhovaný kód verze APK", | ||||||
|     "dontSortReleasesList": "Retain release order from API", |     "dontSortReleasesList": "Retain release order from API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Weniger offensichtliche Touch-Ziele hervorheben", |     "highlightTouchTargets": "Weniger offensichtliche Touch-Ziele hervorheben", | ||||||
|     "pickExportDir": "Export-Verzeichnis wählen", |     "pickExportDir": "Export-Verzeichnis wählen", | ||||||
|     "autoExportOnChanges": "Automatischer Export bei Änderung(en)", |     "autoExportOnChanges": "Automatischer Export bei Änderung(en)", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Versionen nach regulären Ausdrücken filtern", |     "filterVersionsByRegEx": "Versionen nach regulären Ausdrücken filtern", | ||||||
|     "trySelectingSuggestedVersionCode": "Versuchen, den vorgeschlagenen APK-Versionscode auszuwählen", |     "trySelectingSuggestedVersionCode": "Versuchen, den vorgeschlagenen APK-Versionscode auszuwählen", | ||||||
|     "dontSortReleasesList": "Freigaberelease von der API ordern", |     "dontSortReleasesList": "Freigaberelease von der API ordern", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Highlight less obvious touch targets", |     "highlightTouchTargets": "Highlight less obvious touch targets", | ||||||
|     "pickExportDir": "Pick Export Directory", |     "pickExportDir": "Pick Export Directory", | ||||||
|     "autoExportOnChanges": "Auto-export on changes", |     "autoExportOnChanges": "Auto-export on changes", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filter Versions by Regular Expression", |     "filterVersionsByRegEx": "Filter Versions by Regular Expression", | ||||||
|     "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", |     "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", | ||||||
|     "dontSortReleasesList": "Retain release order from API", |     "dontSortReleasesList": "Retain release order from API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Resaltar objetivos menos obvios", |     "highlightTouchTargets": "Resaltar objetivos menos obvios", | ||||||
|     "pickExportDir": "Selecciona el Directorio para Exportar", |     "pickExportDir": "Selecciona el Directorio para Exportar", | ||||||
|     "autoExportOnChanges": "Auto Exportar cuando haya cambios", |     "autoExportOnChanges": "Auto Exportar cuando haya cambios", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filtrar por Versiones", |     "filterVersionsByRegEx": "Filtrar por Versiones", | ||||||
|     "trySelectingSuggestedVersionCode": "Prueba seleccionando la versionCode APK sugerida", |     "trySelectingSuggestedVersionCode": "Prueba seleccionando la versionCode APK sugerida", | ||||||
|     "dontSortReleasesList": "Mantener el order de publicación desde API", |     "dontSortReleasesList": "Mantener el order de publicación desde API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "اهداف لمسی کمتر واضح را برجسته کنید", |     "highlightTouchTargets": "اهداف لمسی کمتر واضح را برجسته کنید", | ||||||
|     "pickExportDir": "فهرست صادرات را انتخاب کنید", |     "pickExportDir": "فهرست صادرات را انتخاب کنید", | ||||||
|     "autoExportOnChanges": "صادرات خودکار تغییرات", |     "autoExportOnChanges": "صادرات خودکار تغییرات", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "فیلتر کردن نسخه ها با RegEx", |     "filterVersionsByRegEx": "فیلتر کردن نسخه ها با RegEx", | ||||||
|     "trySelectingSuggestedVersionCode": "نسخه پیشنهادی APK نسخه کد را انتخاب کنید", |     "trySelectingSuggestedVersionCode": "نسخه پیشنهادی APK نسخه کد را انتخاب کنید", | ||||||
|     "dontSortReleasesList": "حفظ سفارش انتشار از API", |     "dontSortReleasesList": "حفظ سفارش انتشار از API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Highlight less obvious touch targets", |     "highlightTouchTargets": "Highlight less obvious touch targets", | ||||||
|     "pickExportDir": "Pick Export Directory", |     "pickExportDir": "Pick Export Directory", | ||||||
|     "autoExportOnChanges": "Auto-export on changes", |     "autoExportOnChanges": "Auto-export on changes", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filter Versions by Regular Expression", |     "filterVersionsByRegEx": "Filter Versions by Regular Expression", | ||||||
|     "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", |     "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", | ||||||
|     "dontSortReleasesList": "Retain release order from API", |     "dontSortReleasesList": "Retain release order from API", | ||||||
|   | |||||||
| @@ -255,6 +255,7 @@ | |||||||
|     "highlightTouchTargets": "Emelje ki a kevésbé nyilvánvaló érintési célokat", |     "highlightTouchTargets": "Emelje ki a kevésbé nyilvánvaló érintési célokat", | ||||||
|     "pickExportDir": "Válassza az Exportálási könyvtárat", |     "pickExportDir": "Válassza az Exportálási könyvtárat", | ||||||
|     "autoExportOnChanges": "Auto-exportálás a változások után", |     "autoExportOnChanges": "Auto-exportálás a változások után", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Verziók szűrése reguláris kifejezéssel", |     "filterVersionsByRegEx": "Verziók szűrése reguláris kifejezéssel", | ||||||
|     "trySelectingSuggestedVersionCode": "Próbálja ki a javasolt verziókódú APK-t", |     "trySelectingSuggestedVersionCode": "Próbálja ki a javasolt verziókódú APK-t", | ||||||
|     "dontSortReleasesList": "Az API-ból származó kiadási sorrend megőrzése", |     "dontSortReleasesList": "Az API-ból származó kiadási sorrend megőrzése", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Evidenzia elementi toccabili meno ovvi", |     "highlightTouchTargets": "Evidenzia elementi toccabili meno ovvi", | ||||||
|     "pickExportDir": "Scegli cartella esp.", |     "pickExportDir": "Scegli cartella esp.", | ||||||
|     "autoExportOnChanges": "Auto-esporta dopo modifiche", |     "autoExportOnChanges": "Auto-esporta dopo modifiche", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filtra versioni con espressione regolare", |     "filterVersionsByRegEx": "Filtra versioni con espressione regolare", | ||||||
|     "trySelectingSuggestedVersionCode": "Prova a selezionare APK con versionCode suggerito", |     "trySelectingSuggestedVersionCode": "Prova a selezionare APK con versionCode suggerito", | ||||||
|     "dontSortReleasesList": "Conserva l'ordine di release da API", |     "dontSortReleasesList": "Conserva l'ordine di release da API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "目立たないタップ可能な対象をハイライトする", |     "highlightTouchTargets": "目立たないタップ可能な対象をハイライトする", | ||||||
|     "pickExportDir": "エクスポートディレクトリを選択", |     "pickExportDir": "エクスポートディレクトリを選択", | ||||||
|     "autoExportOnChanges": "変更があった際に自動でエクスポートする", |     "autoExportOnChanges": "変更があった際に自動でエクスポートする", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "正規表現でバージョンをフィルタリングする", |     "filterVersionsByRegEx": "正規表現でバージョンをフィルタリングする", | ||||||
|     "trySelectingSuggestedVersionCode": "提案されたバージョンコードのAPKを選択する", |     "trySelectingSuggestedVersionCode": "提案されたバージョンコードのAPKを選択する", | ||||||
|     "dontSortReleasesList": "APIからのリリース順を保持する", |     "dontSortReleasesList": "APIからのリリース順を保持する", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Markeer minder voor de hand liggende aanraakdoelen.", |     "highlightTouchTargets": "Markeer minder voor de hand liggende aanraakdoelen.", | ||||||
|     "pickExportDir": "Kies de exportmap", |     "pickExportDir": "Kies de exportmap", | ||||||
|     "autoExportOnChanges": "Automatisch exporteren bij wijzigingen", |     "autoExportOnChanges": "Automatisch exporteren bij wijzigingen", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filter versies met een reguliere expressie", |     "filterVersionsByRegEx": "Filter versies met een reguliere expressie", | ||||||
|     "trySelectingSuggestedVersionCode": "Probeer de voorgestelde versiecode APK te selecteren", |     "trySelectingSuggestedVersionCode": "Probeer de voorgestelde versiecode APK te selecteren", | ||||||
|     "dontSortReleasesList": "Volgorde van releases behouden vanuit de API", |     "dontSortReleasesList": "Volgorde van releases behouden vanuit de API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Wyróżnij mniej oczywiste elementy dotykowe", |     "highlightTouchTargets": "Wyróżnij mniej oczywiste elementy dotykowe", | ||||||
|     "pickExportDir": "Wybierz katalog eksportu", |     "pickExportDir": "Wybierz katalog eksportu", | ||||||
|     "autoExportOnChanges": "Automatyczny eksport po wprowadzeniu zmian", |     "autoExportOnChanges": "Automatyczny eksport po wprowadzeniu zmian", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filtruj wersje według wyrażenia regularnego", |     "filterVersionsByRegEx": "Filtruj wersje według wyrażenia regularnego", | ||||||
|     "trySelectingSuggestedVersionCode": "Spróbuj wybierać sugerowany kod wersji APK", |     "trySelectingSuggestedVersionCode": "Spróbuj wybierać sugerowany kod wersji APK", | ||||||
|     "dontSortReleasesList": "Utrzymaj kolejność wydań z interfejsu API", |     "dontSortReleasesList": "Utrzymaj kolejność wydań z interfejsu API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Destaque areas de toque menos óbvias", |     "highlightTouchTargets": "Destaque areas de toque menos óbvias", | ||||||
|     "pickExportDir": "Escolher Diretorio de Exportação", |     "pickExportDir": "Escolher Diretorio de Exportação", | ||||||
|     "autoExportOnChanges": "Auto-exportar em mudanças", |     "autoExportOnChanges": "Auto-exportar em mudanças", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filtrar Versões por Expressão Regular", |     "filterVersionsByRegEx": "Filtrar Versões por Expressão Regular", | ||||||
|     "trySelectingSuggestedVersionCode": "Tente selecionar a versão sugerida", |     "trySelectingSuggestedVersionCode": "Tente selecionar a versão sugerida", | ||||||
|     "dontSortReleasesList": "Reter a ordem de lançamento da API", |     "dontSortReleasesList": "Reter a ordem de lançamento da API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Выделить менее очевидные элементы управления касанием", |     "highlightTouchTargets": "Выделить менее очевидные элементы управления касанием", | ||||||
|     "pickExportDir": "Выбрать каталог для экспорта", |     "pickExportDir": "Выбрать каталог для экспорта", | ||||||
|     "autoExportOnChanges": "Автоэкспорт при изменениях", |     "autoExportOnChanges": "Автоэкспорт при изменениях", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Фильтровать версии по регулярному выражению", |     "filterVersionsByRegEx": "Фильтровать версии по регулярному выражению", | ||||||
|     "trySelectingSuggestedVersionCode": "Попробуйте выбрать предложенный код версии APK", |     "trySelectingSuggestedVersionCode": "Попробуйте выбрать предложенный код версии APK", | ||||||
|     "dontSortReleasesList": "Сохранить порядок релизов от API", |     "dontSortReleasesList": "Сохранить порядок релизов от API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Highlight less obvious touch targets", |     "highlightTouchTargets": "Highlight less obvious touch targets", | ||||||
|     "pickExportDir": "Välj Exportsökväg", |     "pickExportDir": "Välj Exportsökväg", | ||||||
|     "autoExportOnChanges": "Automatisk export vid ändringar", |     "autoExportOnChanges": "Automatisk export vid ändringar", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Filter Versions by Regular Expression", |     "filterVersionsByRegEx": "Filter Versions by Regular Expression", | ||||||
|     "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", |     "trySelectingSuggestedVersionCode": "Try selecting suggested versionCode APK", | ||||||
|     "dontSortReleasesList": "Retain release order from API", |     "dontSortReleasesList": "Retain release order from API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Daha az belirgin dokunma hedeflerini vurgula", |     "highlightTouchTargets": "Daha az belirgin dokunma hedeflerini vurgula", | ||||||
|     "pickExportDir": "Dışa Aktarılacak Klasörü Seç", |     "pickExportDir": "Dışa Aktarılacak Klasörü Seç", | ||||||
|     "autoExportOnChanges": "Değişikliklerde otomatik olarak dışa aktar", |     "autoExportOnChanges": "Değişikliklerde otomatik olarak dışa aktar", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Sürümleri Düzenli İfade ile Filtrele", |     "filterVersionsByRegEx": "Sürümleri Düzenli İfade ile Filtrele", | ||||||
|     "trySelectingSuggestedVersionCode": "Önerilen sürüm kodunu seçmeyi dene", |     "trySelectingSuggestedVersionCode": "Önerilen sürüm kodunu seçmeyi dene", | ||||||
|     "dontSortReleasesList": "API'den sıralama düzenini koru", |     "dontSortReleasesList": "API'den sıralama düzenini koru", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "Đánh dấu các mục tiêu cảm ứng ít rõ ràng hơn", |     "highlightTouchTargets": "Đánh dấu các mục tiêu cảm ứng ít rõ ràng hơn", | ||||||
|     "pickExportDir": "Chọn thư mục xuất", |     "pickExportDir": "Chọn thư mục xuất", | ||||||
|     "autoExportOnChanges": "Tự động xuất khi thay đổi", |     "autoExportOnChanges": "Tự động xuất khi thay đổi", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "Lọc phiên bản theo biểu thức chính quy", |     "filterVersionsByRegEx": "Lọc phiên bản theo biểu thức chính quy", | ||||||
|     "trySelectingSuggestedVersionCode": "Thử chọn APK Mã phiên bản được đề xuất", |     "trySelectingSuggestedVersionCode": "Thử chọn APK Mã phiên bản được đề xuất", | ||||||
|     "dontSortReleasesList": "Giữ lại thứ tự phát hành từ API", |     "dontSortReleasesList": "Giữ lại thứ tự phát hành từ API", | ||||||
|   | |||||||
| @@ -256,6 +256,7 @@ | |||||||
|     "highlightTouchTargets": "突出展示不明显的触摸区域", |     "highlightTouchTargets": "突出展示不明显的触摸区域", | ||||||
|     "pickExportDir": "选择导出文件夹", |     "pickExportDir": "选择导出文件夹", | ||||||
|     "autoExportOnChanges": "数据变更时自动导出", |     "autoExportOnChanges": "数据变更时自动导出", | ||||||
|  |     "includeSettings": "Include settings", | ||||||
|     "filterVersionsByRegEx": "筛选版本号(正则表达式)", |     "filterVersionsByRegEx": "筛选版本号(正则表达式)", | ||||||
|     "trySelectingSuggestedVersionCode": "尝试选择推荐版本的 APK 文件", |     "trySelectingSuggestedVersionCode": "尝试选择推荐版本的 APK 文件", | ||||||
|     "dontSortReleasesList": "保持来自 API 的发行顺序", |     "dontSortReleasesList": "保持来自 API 的发行顺序", | ||||||
|   | |||||||
| @@ -48,12 +48,6 @@ class GitLab extends AppSource { | |||||||
|             label: tr('fallbackToOlderReleases'), defaultValue: true) |             label: tr('fallbackToOlderReleases'), defaultValue: true) | ||||||
|       ] |       ] | ||||||
|     ]; |     ]; | ||||||
|     searchQuerySettingFormItems = [ |  | ||||||
|       GeneratedFormTextField('PAT', |  | ||||||
|           label: tr('gitlabPATLabel').split('(')[0], |  | ||||||
|           password: true, |  | ||||||
|           required: false) |  | ||||||
|     ]; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
| @@ -86,18 +80,8 @@ class GitLab extends AppSource { | |||||||
|   @override |   @override | ||||||
|   Future<Map<String, List<String>>> search(String query, |   Future<Map<String, List<String>>> search(String query, | ||||||
|       {Map<String, dynamic> querySettings = const {}}) async { |       {Map<String, dynamic> querySettings = const {}}) async { | ||||||
|     String? PAT; |  | ||||||
|     if (!hostChanged) { |  | ||||||
|       PAT = await getPATIfAny({}); |  | ||||||
|       if (PAT == null) { |  | ||||||
|         throw CredsNeededError(name); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if ((querySettings['PAT'] as String?)?.isNotEmpty == true) { |  | ||||||
|       PAT = querySettings['PAT']; |  | ||||||
|     } |  | ||||||
|     var url = |     var url = | ||||||
|         'https://$host/api/v4/search?${PAT?.isNotEmpty == true ? 'private_token=$PAT&' : ''}scope=projects&search=${Uri.encodeQueryComponent(query)}'; |         'https://$host/api/v4/projects?search=${Uri.encodeQueryComponent(query)}'; | ||||||
|     var res = await sourceRequest(url); |     var res = await sourceRequest(url); | ||||||
|     if (res.statusCode != 200) { |     if (res.statusCode != 200) { | ||||||
|       throw getObtainiumHttpError(res); |       throw getObtainiumHttpError(res); | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; | |||||||
| // ignore: implementation_imports | // ignore: implementation_imports | ||||||
| import 'package:easy_localization/src/localization.dart'; | import 'package:easy_localization/src/localization.dart'; | ||||||
|  |  | ||||||
| const String currentVersion = '0.14.36'; | const String currentVersion = '0.14.37'; | ||||||
| const String currentReleaseTag = | const String currentReleaseTag = | ||||||
|     'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES |     'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,10 +21,10 @@ class AddAppPage extends StatefulWidget { | |||||||
|   const AddAppPage({super.key}); |   const AddAppPage({super.key}); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   State<AddAppPage> createState() => _AddAppPageState(); |   State<AddAppPage> createState() => AddAppPageState(); | ||||||
| } | } | ||||||
|  |  | ||||||
| class _AddAppPageState extends State<AddAppPage> { | class AddAppPageState extends State<AddAppPage> { | ||||||
|   bool gettingAppInfo = false; |   bool gettingAppInfo = false; | ||||||
|   bool searching = false; |   bool searching = false; | ||||||
|  |  | ||||||
| @@ -36,25 +36,28 @@ class _AddAppPageState extends State<AddAppPage> { | |||||||
|   bool additionalSettingsValid = true; |   bool additionalSettingsValid = true; | ||||||
|   bool inferAppIdIfOptional = true; |   bool inferAppIdIfOptional = true; | ||||||
|   List<String> pickedCategories = []; |   List<String> pickedCategories = []; | ||||||
|   int searchnum = 0; |   int urlInputKey = 0; | ||||||
|   SourceProvider sourceProvider = SourceProvider(); |   SourceProvider sourceProvider = SourceProvider(); | ||||||
|  |  | ||||||
|   @override |   linkFn(String input) { | ||||||
|   Widget build(BuildContext context) { |     try { | ||||||
|     AppsProvider appsProvider = context.read<AppsProvider>(); |       if (input.isEmpty) { | ||||||
|     SettingsProvider settingsProvider = context.watch<SettingsProvider>(); |         throw UnsupportedURLError(); | ||||||
|     NotificationsProvider notificationsProvider = |       } | ||||||
|         context.read<NotificationsProvider>(); |       sourceProvider.getSource(input); | ||||||
|  |       changeUserInput(input, true, false, updateUrlInput: true); | ||||||
|     bool doingSomething = gettingAppInfo || searching; |     } catch (e) { | ||||||
|  |       showError(e, context); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   changeUserInput(String input, bool valid, bool isBuilding, |   changeUserInput(String input, bool valid, bool isBuilding, | ||||||
|         {bool isSearch = false}) { |       {bool updateUrlInput = false}) { | ||||||
|     userInput = input; |     userInput = input; | ||||||
|     if (!isBuilding) { |     if (!isBuilding) { | ||||||
|       setState(() { |       setState(() { | ||||||
|           if (isSearch) { |         if (updateUrlInput) { | ||||||
|             searchnum++; |           urlInputKey++; | ||||||
|         } |         } | ||||||
|         var prevHost = pickedSource?.host; |         var prevHost = pickedSource?.host; | ||||||
|         try { |         try { | ||||||
| @@ -89,6 +92,15 @@ class _AddAppPageState extends State<AddAppPage> { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     AppsProvider appsProvider = context.read<AppsProvider>(); | ||||||
|  |     SettingsProvider settingsProvider = context.watch<SettingsProvider>(); | ||||||
|  |     NotificationsProvider notificationsProvider = | ||||||
|  |         context.read<NotificationsProvider>(); | ||||||
|  |  | ||||||
|  |     bool doingSomething = gettingAppInfo || searching; | ||||||
|  |  | ||||||
|     Future<bool> getTrackOnlyConfirmationIfNeeded(bool userPickedTrackOnly, |     Future<bool> getTrackOnlyConfirmationIfNeeded(bool userPickedTrackOnly, | ||||||
|         {bool ignoreHideSetting = false}) async { |         {bool ignoreHideSetting = false}) async { | ||||||
|       var useTrackOnly = userPickedTrackOnly || pickedSource!.enforceTrackOnly; |       var useTrackOnly = userPickedTrackOnly || pickedSource!.enforceTrackOnly; | ||||||
| @@ -205,7 +217,7 @@ class _AddAppPageState extends State<AddAppPage> { | |||||||
|           children: [ |           children: [ | ||||||
|             Expanded( |             Expanded( | ||||||
|                 child: GeneratedForm( |                 child: GeneratedForm( | ||||||
|                     key: Key(searchnum.toString()), |                     key: Key(urlInputKey.toString()), | ||||||
|                     items: [ |                     items: [ | ||||||
|                       [ |                       [ | ||||||
|                         GeneratedFormTextField('appSourceURL', |                         GeneratedFormTextField('appSourceURL', | ||||||
| @@ -325,7 +337,7 @@ class _AddAppPageState extends State<AddAppPage> { | |||||||
|                     ); |                     ); | ||||||
|                   }); |                   }); | ||||||
|           if (selectedUrls != null && selectedUrls.isNotEmpty) { |           if (selectedUrls != null && selectedUrls.isNotEmpty) { | ||||||
|             changeUserInput(selectedUrls[0], true, false, isSearch: true); |             changeUserInput(selectedUrls[0], true, false, updateUrlInput: true); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } catch (e) { |       } catch (e) { | ||||||
|   | |||||||
| @@ -1,7 +1,11 @@ | |||||||
|  | import 'dart:async'; | ||||||
|  |  | ||||||
| import 'package:animations/animations.dart'; | import 'package:animations/animations.dart'; | ||||||
|  | import 'package:app_links/app_links.dart'; | ||||||
| import 'package:easy_localization/easy_localization.dart'; | import 'package:easy_localization/easy_localization.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:flutter/services.dart'; | import 'package:flutter/services.dart'; | ||||||
|  | import 'package:obtainium/custom_errors.dart'; | ||||||
| import 'package:obtainium/pages/add_app.dart'; | import 'package:obtainium/pages/add_app.dart'; | ||||||
| import 'package:obtainium/pages/apps.dart'; | import 'package:obtainium/pages/apps.dart'; | ||||||
| import 'package:obtainium/pages/import_export.dart'; | import 'package:obtainium/pages/import_export.dart'; | ||||||
| @@ -30,20 +34,75 @@ class _HomePageState extends State<HomePage> { | |||||||
|   bool isReversing = false; |   bool isReversing = false; | ||||||
|   int prevAppCount = -1; |   int prevAppCount = -1; | ||||||
|   bool prevIsLoading = true; |   bool prevIsLoading = true; | ||||||
|  |   late AppLinks _appLinks; | ||||||
|  |   StreamSubscription<Uri>? _linkSubscription; | ||||||
|  |   bool isLinkActivity = false; | ||||||
|  |  | ||||||
|   List<NavigationPageItem> pages = [ |   List<NavigationPageItem> pages = [ | ||||||
|     NavigationPageItem(tr('appsString'), Icons.apps, |     NavigationPageItem(tr('appsString'), Icons.apps, | ||||||
|         AppsPage(key: GlobalKey<AppsPageState>())), |         AppsPage(key: GlobalKey<AppsPageState>())), | ||||||
|     NavigationPageItem(tr('addApp'), Icons.add, const AddAppPage()), |     NavigationPageItem( | ||||||
|  |         tr('addApp'), Icons.add, AddAppPage(key: GlobalKey<AddAppPageState>())), | ||||||
|     NavigationPageItem( |     NavigationPageItem( | ||||||
|         tr('importExport'), Icons.import_export, const ImportExportPage()), |         tr('importExport'), Icons.import_export, const ImportExportPage()), | ||||||
|     NavigationPageItem(tr('settings'), Icons.settings, const SettingsPage()) |     NavigationPageItem(tr('settings'), Icons.settings, const SettingsPage()) | ||||||
|   ]; |   ]; | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   void initState() { | ||||||
|     AppsProvider appsProvider = context.watch<AppsProvider>(); |     super.initState(); | ||||||
|     SettingsProvider settingsProvider = context.watch<SettingsProvider>(); |     initDeepLinks(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Future<void> initDeepLinks() async { | ||||||
|  |     _appLinks = AppLinks(); | ||||||
|  |  | ||||||
|  |     goToAddApp(String data) async { | ||||||
|  |       switchToPage(1); | ||||||
|  |       while ( | ||||||
|  |           (pages[1].widget.key as GlobalKey<AddAppPageState>?)?.currentState == | ||||||
|  |               null) { | ||||||
|  |         await Future.delayed(const Duration(microseconds: 1)); | ||||||
|  |       } | ||||||
|  |       (pages[1].widget.key as GlobalKey<AddAppPageState>?) | ||||||
|  |           ?.currentState | ||||||
|  |           ?.linkFn(data); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     interpretLink(Uri uri) async { | ||||||
|  |       isLinkActivity = true; | ||||||
|  |       var action = uri.host; | ||||||
|  |       var data = uri.path.length > 1 ? uri.path.substring(1) : ""; | ||||||
|  |       try { | ||||||
|  |         if (action == 'add') { | ||||||
|  |           await goToAddApp(data); | ||||||
|  |         } else if (action == 'app') { | ||||||
|  |           await context | ||||||
|  |               .read<AppsProvider>() | ||||||
|  |               .import('{ "apps": [${Uri.decodeComponent(data)}] }'); | ||||||
|  |         } else if (action == 'apps') { | ||||||
|  |           await context | ||||||
|  |               .read<AppsProvider>() | ||||||
|  |               .import('{ "apps": ${Uri.decodeComponent(data)} }'); | ||||||
|  |         } else { | ||||||
|  |           throw ObtainiumError(tr('unknown')); | ||||||
|  |         } | ||||||
|  |       } catch (e) { | ||||||
|  |         showError(e, context); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Check initial link if app was in cold state (terminated) | ||||||
|  |     final appLink = await _appLinks.getInitialAppLink(); | ||||||
|  |     if (appLink != null) { | ||||||
|  |       await interpretLink(appLink); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Handle link when app is in warm state (front or background) | ||||||
|  |     _linkSubscription = _appLinks.uriLinkStream.listen((uri) async { | ||||||
|  |       await interpretLink(uri); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   setIsReversing(int targetIndex) { |   setIsReversing(int targetIndex) { | ||||||
|     bool reversing = selectedIndexHistory.isNotEmpty && |     bool reversing = selectedIndexHistory.isNotEmpty && | ||||||
| @@ -77,11 +136,17 @@ class _HomePageState extends State<HomePage> { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     AppsProvider appsProvider = context.watch<AppsProvider>(); | ||||||
|  |     SettingsProvider settingsProvider = context.watch<SettingsProvider>(); | ||||||
|  |  | ||||||
|     if (!prevIsLoading && |     if (!prevIsLoading && | ||||||
|         prevAppCount >= 0 && |         prevAppCount >= 0 && | ||||||
|         appsProvider.apps.length > prevAppCount && |         appsProvider.apps.length > prevAppCount && | ||||||
|         selectedIndexHistory.isNotEmpty && |         selectedIndexHistory.isNotEmpty && | ||||||
|         selectedIndexHistory.last == 1) { |         selectedIndexHistory.last == 1 && | ||||||
|  |         !isLinkActivity) { | ||||||
|       switchToPage(0); |       switchToPage(0); | ||||||
|     } |     } | ||||||
|     prevAppCount = appsProvider.apps.length; |     prevAppCount = appsProvider.apps.length; | ||||||
| @@ -129,6 +194,11 @@ class _HomePageState extends State<HomePage> { | |||||||
|           ), |           ), | ||||||
|         ), |         ), | ||||||
|         onWillPop: () async { |         onWillPop: () async { | ||||||
|  |           if (isLinkActivity && | ||||||
|  |               selectedIndexHistory.length == 1 && | ||||||
|  |               selectedIndexHistory.last == 1) { | ||||||
|  |             return true; | ||||||
|  |           } | ||||||
|           setIsReversing(selectedIndexHistory.length >= 2 |           setIsReversing(selectedIndexHistory.length >= 2 | ||||||
|               ? selectedIndexHistory.reversed.toList()[1] |               ? selectedIndexHistory.reversed.toList()[1] | ||||||
|               : 0); |               : 0); | ||||||
| @@ -143,4 +213,10 @@ class _HomePageState extends State<HomePage> { | |||||||
|               ?.clearSelected(); |               ?.clearSelected(); | ||||||
|         }); |         }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void dispose() { | ||||||
|  |     super.dispose(); | ||||||
|  |     _linkSubscription?.cancel(); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -106,7 +106,7 @@ class _ImportExportPageState extends State<ImportExportPage> { | |||||||
|     runObtainiumExport({bool pickOnly = false}) async { |     runObtainiumExport({bool pickOnly = false}) async { | ||||||
|       HapticFeedback.selectionClick(); |       HapticFeedback.selectionClick(); | ||||||
|       appsProvider |       appsProvider | ||||||
|           .exportApps( |           .export( | ||||||
|               pickOnly: |               pickOnly: | ||||||
|                   pickOnly || (await settingsProvider.getExportDir()) == null, |                   pickOnly || (await settingsProvider.getExportDir()) == null, | ||||||
|               sp: settingsProvider) |               sp: settingsProvider) | ||||||
| @@ -132,7 +132,7 @@ class _ImportExportPageState extends State<ImportExportPage> { | |||||||
|           } catch (e) { |           } catch (e) { | ||||||
|             throw ObtainiumError(tr('invalidInput')); |             throw ObtainiumError(tr('invalidInput')); | ||||||
|           } |           } | ||||||
|           appsProvider.importApps(data).then((value) { |           appsProvider.import(data).then((value) { | ||||||
|             var cats = settingsProvider.categories; |             var cats = settingsProvider.categories; | ||||||
|             appsProvider.apps.forEach((key, value) { |             appsProvider.apps.forEach((key, value) { | ||||||
|               for (var c in value.app.categories) { |               for (var c in value.app.categories) { | ||||||
| @@ -143,7 +143,10 @@ class _ImportExportPageState extends State<ImportExportPage> { | |||||||
|             }); |             }); | ||||||
|             appsProvider.addMissingCategories(settingsProvider); |             appsProvider.addMissingCategories(settingsProvider); | ||||||
|             showMessage( |             showMessage( | ||||||
|                 tr('importedX', args: [plural('apps', value)]), context); |                 '${tr('importedX', args: [ | ||||||
|  |                       plural('apps', value.key) | ||||||
|  |                     ])}${value.value ? ' + ${tr('settings')}' : ''}', | ||||||
|  |                 context); | ||||||
|           }); |           }); | ||||||
|         } else { |         } else { | ||||||
|           // User canceled the picker |           // User canceled the picker | ||||||
| @@ -388,6 +391,14 @@ class _ImportExportPageState extends State<ImportExportPage> { | |||||||
|                                               defaultValue: settingsProvider |                                               defaultValue: settingsProvider | ||||||
|                                                   .autoExportOnChanges, |                                                   .autoExportOnChanges, | ||||||
|                                             ) |                                             ) | ||||||
|  |                                           ], | ||||||
|  |                                           [ | ||||||
|  |                                             GeneratedFormSwitch( | ||||||
|  |                                               'exportSettings', | ||||||
|  |                                               label: tr('includeSettings'), | ||||||
|  |                                               defaultValue: settingsProvider | ||||||
|  |                                                   .exportSettings, | ||||||
|  |                                             ) | ||||||
|                                           ] |                                           ] | ||||||
|                                         ], |                                         ], | ||||||
|                                         onValueChanges: |                                         onValueChanges: | ||||||
| @@ -400,6 +411,12 @@ class _ImportExportPageState extends State<ImportExportPage> { | |||||||
|                                                       'autoExportOnChanges'] == |                                                       'autoExportOnChanges'] == | ||||||
|                                                   true; |                                                   true; | ||||||
|                                             } |                                             } | ||||||
|  |                                             if (value['exportSettings'] != | ||||||
|  |                                                 null) { | ||||||
|  |                                               settingsProvider.exportSettings = | ||||||
|  |                                                   value['exportSettings'] == | ||||||
|  |                                                       true; | ||||||
|  |                                             } | ||||||
|                                           } |                                           } | ||||||
|                                         }), |                                         }), | ||||||
|                                   ], |                                   ], | ||||||
|   | |||||||
| @@ -974,7 +974,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     notifyListeners(); |     notifyListeners(); | ||||||
|     exportApps(isAuto: true); |     export(isAuto: true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future<void> removeApps(List<String> appIds) async { |   Future<void> removeApps(List<String> appIds) async { | ||||||
| @@ -996,7 +996,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|     } |     } | ||||||
|     if (appIds.isNotEmpty) { |     if (appIds.isNotEmpty) { | ||||||
|       notifyListeners(); |       notifyListeners(); | ||||||
|       exportApps(isAuto: true); |       export(isAuto: true); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1173,7 +1173,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|     return updateAppIds; |     return updateAppIds; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future<String?> exportApps( |   Future<String?> export( | ||||||
|       {bool pickOnly = false, isAuto = false, SettingsProvider? sp}) async { |       {bool pickOnly = false, isAuto = false, SettingsProvider? sp}) async { | ||||||
|     SettingsProvider settingsProvider = sp ?? this.settingsProvider; |     SettingsProvider settingsProvider = sp ?? this.settingsProvider; | ||||||
|     var exportDir = await settingsProvider.getExportDir(); |     var exportDir = await settingsProvider.getExportDir(); | ||||||
| @@ -1203,12 +1203,22 @@ class AppsProvider with ChangeNotifier { | |||||||
|     } |     } | ||||||
|     String? returnPath; |     String? returnPath; | ||||||
|     if (!pickOnly) { |     if (!pickOnly) { | ||||||
|  |       Map<String, dynamic> finalExport = {}; | ||||||
|  |       finalExport['apps'] = apps.values.map((e) => e.app.toJson()).toList(); | ||||||
|  |       if (settingsProvider.exportSettings) { | ||||||
|  |         finalExport['settings'] = Map<String, Object?>.fromEntries( | ||||||
|  |             (settingsProvider.prefs | ||||||
|  |                     ?.getKeys() | ||||||
|  |                     .map((key) => | ||||||
|  |                         MapEntry(key, settingsProvider.prefs?.get(key))) | ||||||
|  |                     .toList()) ?? | ||||||
|  |                 []); | ||||||
|  |       } | ||||||
|       var result = await saf.createFile(exportDir, |       var result = await saf.createFile(exportDir, | ||||||
|           displayName: |           displayName: | ||||||
|               '${tr('obtainiumExportHyphenatedLowercase')}-${DateTime.now().toIso8601String().replaceAll(':', '-')}${isAuto ? '-auto' : ''}.json', |               '${tr('obtainiumExportHyphenatedLowercase')}-${DateTime.now().toIso8601String().replaceAll(':', '-')}${isAuto ? '-auto' : ''}.json', | ||||||
|           mimeType: 'application/json', |           mimeType: 'application/json', | ||||||
|           bytes: Uint8List.fromList(utf8.encode( |           bytes: Uint8List.fromList(utf8.encode(jsonEncode(finalExport)))); | ||||||
|               jsonEncode(apps.values.map((e) => e.app.toJson()).toList())))); |  | ||||||
|       if (result == null) { |       if (result == null) { | ||||||
|         throw ObtainiumError(tr('unexpectedError')); |         throw ObtainiumError(tr('unexpectedError')); | ||||||
|       } |       } | ||||||
| @@ -1218,8 +1228,11 @@ class AppsProvider with ChangeNotifier { | |||||||
|     return returnPath; |     return returnPath; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future<int> importApps(String appsJSON) async { |   Future<MapEntry<int, bool>> import(String appsJSON) async { | ||||||
|     List<App> importedApps = (jsonDecode(appsJSON) as List<dynamic>) |     var decodedJSON = jsonDecode(appsJSON); | ||||||
|  |     var newFormat = !(decodedJSON is List); | ||||||
|  |     List<App> importedApps = | ||||||
|  |         ((newFormat ? decodedJSON['apps'] : decodedJSON) as List<dynamic>) | ||||||
|             .map((e) => App.fromJson(e)) |             .map((e) => App.fromJson(e)) | ||||||
|             .toList(); |             .toList(); | ||||||
|     while (loadingApps) { |     while (loadingApps) { | ||||||
| @@ -1232,7 +1245,20 @@ class AppsProvider with ChangeNotifier { | |||||||
|     } |     } | ||||||
|     await saveApps(importedApps, onlyIfExists: false); |     await saveApps(importedApps, onlyIfExists: false); | ||||||
|     notifyListeners(); |     notifyListeners(); | ||||||
|     return importedApps.length; |     if (newFormat && decodedJSON['settings'] != null) { | ||||||
|  |       var settingsMap = decodedJSON['settings'] as Map<String, Object?>; | ||||||
|  |       settingsMap.forEach((key, value) { | ||||||
|  |         if (value is int) { | ||||||
|  |           settingsProvider.prefs?.setInt(key, value); | ||||||
|  |         } else if (value is bool) { | ||||||
|  |           settingsProvider.prefs?.setBool(key, value); | ||||||
|  |         } else { | ||||||
|  |           settingsProvider.prefs?.setString(key, value as String); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |     return MapEntry<int, bool>( | ||||||
|  |         importedApps.length, newFormat && decodedJSON['settings'] != null); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   | |||||||
| @@ -213,7 +213,8 @@ class SettingsProvider with ChangeNotifier { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   String? getSettingString(String settingId) { |   String? getSettingString(String settingId) { | ||||||
|     return prefs?.getString(settingId); |     String? str = prefs?.getString(settingId); | ||||||
|  |     return str?.isNotEmpty == true ? str : null; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void setSettingString(String settingId, String value) { |   void setSettingString(String settingId, String value) { | ||||||
| @@ -415,4 +416,13 @@ class SettingsProvider with ChangeNotifier { | |||||||
|     prefs?.setBool('onlyCheckInstalledOrTrackOnlyApps', val); |     prefs?.setBool('onlyCheckInstalledOrTrackOnlyApps', val); | ||||||
|     notifyListeners(); |     notifyListeners(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   bool get exportSettings { | ||||||
|  |     return prefs?.getBool('exportSettings') ?? false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   set exportSettings(bool val) { | ||||||
|  |     prefs?.setBool('exportSettings', val); | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -42,6 +42,14 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.0.10" |     version: "2.0.10" | ||||||
|  |   app_links: | ||||||
|  |     dependency: "direct main" | ||||||
|  |     description: | ||||||
|  |       name: app_links | ||||||
|  |       sha256: "4e392b5eba997df356ca6021f28431ce1cfeb16758699553a94b13add874a3bb" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "3.5.0" | ||||||
|   archive: |   archive: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -94,10 +102,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: cli_util |       name: cli_util | ||||||
|       sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 |       sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "0.4.0" |     version: "0.4.1" | ||||||
|   clock: |   clock: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -350,6 +358,14 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "8.2.4" |     version: "8.2.4" | ||||||
|  |   gtk: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: gtk | ||||||
|  |       sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "2.1.0" | ||||||
|   hsluv: |   hsluv: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
| @@ -807,10 +823,10 @@ packages: | |||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: url_launcher |       name: url_launcher | ||||||
|       sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba |       sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.2.1" |     version: "6.2.2" | ||||||
|   url_launcher_android: |   url_launcher_android: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -831,10 +847,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: url_launcher_linux |       name: url_launcher_linux | ||||||
|       sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" |       sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.1.0" |     version: "3.1.1" | ||||||
|   url_launcher_macos: |   url_launcher_macos: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -855,26 +871,26 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: url_launcher_web |       name: url_launcher_web | ||||||
|       sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" |       sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.2.1" |     version: "2.2.2" | ||||||
|   url_launcher_windows: |   url_launcher_windows: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: url_launcher_windows |       name: url_launcher_windows | ||||||
|       sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" |       sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.1.0" |     version: "3.1.1" | ||||||
|   uuid: |   uuid: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: uuid |       name: uuid | ||||||
|       sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921 |       sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "4.2.1" |     version: "4.2.2" | ||||||
|   vector_math: |   vector_math: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -903,10 +919,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: webview_flutter_android |       name: webview_flutter_android | ||||||
|       sha256: "8326ee235f87605a2bfc444a4abc897f4abc78d83f054ba7d3d1074ce82b4fbf" |       sha256: e313dcdf45d4c95bcb8960351ef2389b7f0687b90bc92483f7f7983ae5758456 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.12.1" |     version: "3.13.0" | ||||||
|   webview_flutter_platform_interface: |   webview_flutter_platform_interface: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev | |||||||
| # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | ||||||
| # In Windows, build-name is used as the major, minor, and patch parts | # In Windows, build-name is used as the major, minor, and patch parts | ||||||
| # of the product and file versions while build-number is used as the build suffix. | # of the product and file versions while build-number is used as the build suffix. | ||||||
| version: 0.14.36+230 # When changing this, update the tag in main() accordingly | version: 0.14.37+231 # When changing this, update the tag in main() accordingly | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   sdk: '>=3.0.0 <4.0.0' |   sdk: '>=3.0.0 <4.0.0' | ||||||
| @@ -67,6 +67,7 @@ dependencies: | |||||||
|   connectivity_plus: ^5.0.0 |   connectivity_plus: ^5.0.0 | ||||||
|   shared_storage: ^0.8.0 |   shared_storage: ^0.8.0 | ||||||
|   crypto: ^3.0.3 |   crypto: ^3.0.3 | ||||||
|  |   app_links: ^3.5.0 | ||||||
|  |  | ||||||
| dev_dependencies: | dev_dependencies: | ||||||
|   flutter_test: |   flutter_test: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user