* [PATCH pve_flutter_frontend 1/4] chore: upgrade dependencies based on flutter v3.41
2026-04-10 15:09 [PATCH proxmox{_login_manager,_dart_api_client}/pve_flutter_frontend 0/7] upgrade dependencies based on flutter v3.41 and migrate deprecated members Shan Shaji
@ 2026-04-10 15:09 ` Shan Shaji
2026-04-10 15:09 ` [PATCH pve_flutter_frontend 2/4] fix: breaking changes due to the upgrade of font_awesome_flutter to v11 Shan Shaji
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Shan Shaji @ 2026-04-10 15:09 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
android/app/build.gradle | 2 +-
ios/Flutter/AppFrameworkInfo.plist | 2 -
ios/Podfile.lock | 17 +--
ios/Runner.xcodeproj/project.pbxproj | 4 -
pubspec.lock | 212 ++++++++++++++-------------
5 files changed, 117 insertions(+), 120 deletions(-)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 9892795..2475f71 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -54,7 +54,7 @@ android {
defaultConfig {
applicationId namespace
- minSdkVersion 23
+ minSdkVersion flutter.minSdkVersion
targetSdkVersion 36
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
index 1dc6cf7..391a902 100644
--- a/ios/Flutter/AppFrameworkInfo.plist
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -20,7 +20,5 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
- <key>MinimumOSVersion</key>
- <string>13.0</string>
</dict>
</plist>
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 12e8c51..702f80a 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -12,12 +12,7 @@ PODS:
- flutter_inappwebview_ios/Core (0.0.1):
- Flutter
- OrderedSet (~> 6.0.3)
- - objective_c (0.0.1):
- - Flutter
- OrderedSet (6.0.3)
- - path_provider_foundation (0.0.1):
- - Flutter
- - FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
@@ -29,8 +24,6 @@ DEPENDENCIES:
- cupertino_http (from `.symlinks/plugins/cupertino_http/darwin`)
- Flutter (from `Flutter`)
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
- - objective_c (from `.symlinks/plugins/objective_c/ios`)
- - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@@ -47,10 +40,6 @@ EXTERNAL SOURCES:
:path: Flutter
flutter_inappwebview_ios:
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
- objective_c:
- :path: ".symlinks/plugins/objective_c/ios"
- path_provider_foundation:
- :path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
url_launcher_ios:
@@ -61,11 +50,9 @@ SPEC CHECKSUMS:
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
- objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
- path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
- shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
- url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
+ shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
+ url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 376b910..a9d4fd5 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -281,14 +281,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
- inputPaths = (
- );
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
- outputPaths = (
- );
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
diff --git a/pubspec.lock b/pubspec.lock
index d22e5ed..ecaab97 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,18 +5,18 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
- sha256: dd3d2ad434b9510001d089e8de7556d50c834481b9abc2891a0184a8493a19dc
+ sha256: "8d7ff3948166b8ec5da0fbb5962000926b8e02f2ed9b3e51d1738905fbd4c98d"
url: "https://pub.dev"
source: hosted
- version: "89.0.0"
+ version: "93.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
- sha256: c22b6e7726d1f9e5db58c7251606076a71ca0dbcf76116675edfadbec0c9e875
+ sha256: de7148ed2fcec579b19f122c1800933dfa028f6d9fd38a152b04b1516cec120b
url: "https://pub.dev"
source: hosted
- version: "8.2.0"
+ version: "10.0.1"
args:
dependency: transitive
description:
@@ -29,10 +29,10 @@ packages:
dependency: transitive
description:
name: async
- sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
+ sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
url: "https://pub.dev"
source: hosted
- version: "2.13.0"
+ version: "2.13.1"
biometric_storage:
dependency: transitive
description:
@@ -53,34 +53,34 @@ packages:
dependency: transitive
description:
name: build
- sha256: "5b887c55a0f734b433b3b2d89f9cd1f99eb636b17e268a5b4259258bc916504b"
+ sha256: aadd943f4f8cc946882c954c187e6115a84c98c81ad1d9c6cbf0895a8c85da9c
url: "https://pub.dev"
source: hosted
- version: "4.0.0"
+ version: "4.0.5"
build_config:
dependency: transitive
description:
name: build_config
- sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187"
+ sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71"
url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.3.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
- sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa"
+ sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957
url: "https://pub.dev"
source: hosted
- version: "4.0.4"
+ version: "4.1.1"
build_runner:
dependency: "direct dev"
description:
name: build_runner
- sha256: "804c47c936df75e1911c19a4fb8c46fa8ff2b3099b9f2b2aa4726af3774f734b"
+ sha256: "521daf8d189deb79ba474e43a696b41c49fb3987818dbacf3308f1e03673a75e"
url: "https://pub.dev"
source: hosted
- version: "2.8.0"
+ version: "2.13.1"
built_collection:
dependency: "direct main"
description:
@@ -93,26 +93,26 @@ packages:
dependency: "direct main"
description:
name: built_value
- sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d
+ sha256: "0730c18c770d05636a8f945c32a4d7d81cb6e0f0148c8db4ad12e7748f7e49af"
url: "https://pub.dev"
source: hosted
- version: "8.12.0"
+ version: "8.12.5"
built_value_generator:
dependency: "direct dev"
description:
name: built_value_generator
- sha256: "65f5823a2c4158384ebc845218e19286fdf5dd04f8ac2cf607b01a502be40b1b"
+ sha256: ebdc4dbc63bcdb8c63eb39569bc1da8594d998862449b8dc0e064b7b999d7c96
url: "https://pub.dev"
source: hosted
- version: "8.12.0"
+ version: "8.12.5"
characters:
dependency: transitive
description:
name: characters
- sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
+ sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
url: "https://pub.dev"
source: hosted
- version: "1.4.0"
+ version: "1.4.1"
checked_yaml:
dependency: transitive
description:
@@ -129,14 +129,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.2"
+ code_assets:
+ dependency: transitive
+ description:
+ name: code_assets
+ sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
code_builder:
dependency: transitive
description:
name: code_builder
- sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243"
+ sha256: "6a6cab2ba4680d6423f34a9b972a4c9a94ebe1b62ecec4e1a1f2cba91fd1319d"
url: "https://pub.dev"
source: hosted
- version: "4.11.0"
+ version: "4.11.1"
collection:
dependency: "direct main"
description:
@@ -157,42 +165,42 @@ packages:
dependency: transitive
description:
name: cronet_http
- sha256: "1b99ad5ae81aa9d2f12900e5f17d3681f3828629bb7f7fe7ad88076a34209840"
+ sha256: "8e77bc6f203e0bc9126e6a9092508a3435dbcb04da3b53ed1a358909385c5e0e"
url: "https://pub.dev"
source: hosted
- version: "1.5.0"
+ version: "1.8.0"
crypto:
dependency: "direct main"
description:
name: crypto
- sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
+ sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
url: "https://pub.dev"
source: hosted
- version: "3.0.6"
+ version: "3.0.7"
cupertino_http:
dependency: transitive
description:
name: cupertino_http
- sha256: "72187f715837290a63479a5b0ae709f4fedad0ed6bd0441c275eceaa02d5abae"
+ sha256: "82cbec60c90bf785a047a9525688b6dacac444e177e1d5a5876963d3c50369e8"
url: "https://pub.dev"
source: hosted
- version: "2.3.0"
+ version: "2.4.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
- sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
+ sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
url: "https://pub.dev"
source: hosted
- version: "1.0.8"
+ version: "1.0.9"
dart_style:
dependency: transitive
description:
name: dart_style
- sha256: c87dfe3d56f183ffe9106a18aebc6db431fc7c98c31a54b952a77f3d54a85697
+ sha256: "29f7ecc274a86d32920b1d9cfc7502fa87220da41ec60b55f329559d5732e2b2"
url: "https://pub.dev"
source: hosted
- version: "3.1.2"
+ version: "3.1.7"
fake_async:
dependency: transitive
description:
@@ -205,10 +213,10 @@ packages:
dependency: transitive
description:
name: ffi
- sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
+ sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
url: "https://pub.dev"
source: hosted
- version: "2.1.4"
+ version: "2.2.0"
file:
dependency: transitive
description:
@@ -250,10 +258,10 @@ packages:
dependency: transitive
description:
name: flutter_inappwebview_internal_annotations
- sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd"
+ sha256: e30fba942e3debea7b7e6cdd4f0f59ce89dd403a9865193e3221293b6d1544c6
url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.3.0"
flutter_inappwebview_ios:
dependency: transitive
description:
@@ -316,18 +324,10 @@ packages:
dependency: "direct main"
description:
name: font_awesome_flutter
- sha256: "27af5982e6c510dec1ba038eff634fa284676ee84e3fd807225c80c4ad869177"
- url: "https://pub.dev"
- source: hosted
- version: "10.10.0"
- frontend_server_client:
- dependency: transitive
- description:
- name: frontend_server_client
- sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
+ sha256: b9011df3a1fa02993630b8fb83526368cf2206a711259830325bab2f1d2a4eb0
url: "https://pub.dev"
source: hosted
- version: "4.0.0"
+ version: "10.12.0"
glob:
dependency: transitive
description:
@@ -344,14 +344,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
+ hooks:
+ dependency: transitive
+ description:
+ name: hooks
+ sha256: e79ed1e8e1929bc6ecb6ec85f0cb519c887aa5b423705ded0d0f2d9226def388
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
http:
dependency: transitive
description:
name: http
- sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
+ sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
url: "https://pub.dev"
source: hosted
- version: "1.5.0"
+ version: "1.6.0"
http_multi_server:
dependency: transitive
description:
@@ -396,18 +404,18 @@ packages:
dependency: transitive
description:
name: jni
- sha256: d2c361082d554d4593c3012e26f6b188f902acd291330f13d6427641a92b3da1
+ sha256: "8706a77e94c76fe9ec9315e18949cc9479cc03af97085ca9c1077b61323ea12d"
url: "https://pub.dev"
source: hosted
- version: "0.14.2"
+ version: "0.15.2"
json_annotation:
dependency: transitive
description:
name: json_annotation
- sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
+ sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8
url: "https://pub.dev"
source: hosted
- version: "4.9.0"
+ version: "4.11.0"
leak_tracker:
dependency: transitive
description:
@@ -436,10 +444,10 @@ packages:
dependency: transitive
description:
name: lints
- sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
+ sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df"
url: "https://pub.dev"
source: hosted
- version: "6.0.0"
+ version: "6.1.0"
logging:
dependency: transitive
description:
@@ -452,26 +460,26 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
+ sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
url: "https://pub.dev"
source: hosted
- version: "0.12.17"
+ version: "0.12.19"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+ sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
url: "https://pub.dev"
source: hosted
- version: "0.11.1"
+ version: "0.13.0"
meta:
dependency: "direct main"
description:
name: meta
- sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
+ sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
- version: "1.16.0"
+ version: "1.17.0"
mime:
dependency: transitive
description:
@@ -480,6 +488,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
+ native_toolchain_c:
+ dependency: transitive
+ description:
+ name: native_toolchain_c
+ sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.17.6"
nested:
dependency: transitive
description:
@@ -492,10 +508,10 @@ packages:
dependency: transitive
description:
name: objective_c
- sha256: "9f034ba1eeca53ddb339bc8f4813cb07336a849cd735559b60cdc068ecce2dc7"
+ sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52"
url: "https://pub.dev"
source: hosted
- version: "7.1.0"
+ version: "9.3.0"
package_config:
dependency: transitive
description:
@@ -524,18 +540,18 @@ packages:
dependency: transitive
description:
name: path_provider_android
- sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
+ sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba"
url: "https://pub.dev"
source: hosted
- version: "2.2.18"
+ version: "2.2.23"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
- sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
+ sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
url: "https://pub.dev"
source: hosted
- version: "2.4.2"
+ version: "2.6.0"
path_provider_linux:
dependency: transitive
description:
@@ -642,26 +658,26 @@ packages:
dependency: "direct main"
description:
name: shared_preferences
- sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
+ sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf
url: "https://pub.dev"
source: hosted
- version: "2.5.3"
+ version: "2.5.5"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
- sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e
+ sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53
url: "https://pub.dev"
source: hosted
- version: "2.4.13"
+ version: "2.4.23"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
- sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
+ sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
url: "https://pub.dev"
source: hosted
- version: "2.5.4"
+ version: "2.5.6"
shared_preferences_linux:
dependency: transitive
description:
@@ -674,10 +690,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_platform_interface
- sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
+ sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9"
url: "https://pub.dev"
source: hosted
- version: "2.4.1"
+ version: "2.4.2"
shared_preferences_web:
dependency: transitive
description:
@@ -719,18 +735,18 @@ packages:
dependency: transitive
description:
name: source_gen
- sha256: ccf30b0c9fbcd79d8b6f5bfac23199fb354938436f62475e14aea0f29ee0f800
+ sha256: "732792cfd197d2161a65bb029606a46e0a18ff30ef9e141a7a82172b05ea8ecd"
url: "https://pub.dev"
source: hosted
- version: "4.0.1"
+ version: "4.2.2"
source_span:
dependency: transitive
description:
name: source_span
- sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
+ sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
url: "https://pub.dev"
source: hosted
- version: "1.10.1"
+ version: "1.10.2"
stack_trace:
dependency: transitive
description:
@@ -775,10 +791,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
+ sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
url: "https://pub.dev"
source: hosted
- version: "0.7.6"
+ version: "0.7.10"
typed_data:
dependency: transitive
description:
@@ -799,34 +815,34 @@ packages:
dependency: transitive
description:
name: url_launcher_android
- sha256: "199bc33e746088546a39cc5f36bac5a278c5e53b40cb3196f99e7345fdcfae6b"
+ sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572"
url: "https://pub.dev"
source: hosted
- version: "6.3.22"
+ version: "6.3.29"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
- sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
+ sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
url: "https://pub.dev"
source: hosted
- version: "6.3.4"
+ version: "6.4.1"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
- sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
+ sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
url: "https://pub.dev"
source: hosted
- version: "3.2.1"
+ version: "3.2.2"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
- sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
+ sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
url: "https://pub.dev"
source: hosted
- version: "3.2.3"
+ version: "3.2.5"
url_launcher_platform_interface:
dependency: transitive
description:
@@ -839,18 +855,18 @@ packages:
dependency: transitive
description:
name: url_launcher_web
- sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
+ sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f
url: "https://pub.dev"
source: hosted
- version: "2.4.1"
+ version: "2.4.2"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
- sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
+ sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
url: "https://pub.dev"
source: hosted
- version: "3.1.4"
+ version: "3.1.5"
vector_math:
dependency: transitive
description:
@@ -871,10 +887,10 @@ packages:
dependency: transitive
description:
name: watcher
- sha256: "5bf046f41320ac97a469d506261797f35254fa61c641741ef32dacda98b7d39c"
+ sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635"
url: "https://pub.dev"
source: hosted
- version: "1.1.3"
+ version: "1.2.1"
web:
dependency: transitive
description:
@@ -903,10 +919,10 @@ packages:
dependency: transitive
description:
name: win32
- sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03"
+ sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.dev"
source: hosted
- version: "5.14.0"
+ version: "5.15.0"
xdg_directories:
dependency: transitive
description:
@@ -924,5 +940,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
- dart: ">=3.9.0 <4.0.0"
- flutter: ">=3.35.0"
+ dart: ">=3.10.3 <4.0.0"
+ flutter: ">=3.38.4"
--
2.50.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH pve_flutter_frontend 2/4] fix: breaking changes due to the upgrade of font_awesome_flutter to v11
2026-04-10 15:09 [PATCH proxmox{_login_manager,_dart_api_client}/pve_flutter_frontend 0/7] upgrade dependencies based on flutter v3.41 and migrate deprecated members Shan Shaji
2026-04-10 15:09 ` [PATCH pve_flutter_frontend 1/4] chore: upgrade dependencies based on flutter v3.41 Shan Shaji
@ 2026-04-10 15:09 ` Shan Shaji
2026-04-10 15:09 ` [PATCH pve_flutter_frontend 3/4] fix: migrate to UIScene lifecycle for iOS 26+ compatibility Shan Shaji
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Shan Shaji @ 2026-04-10 15:09 UTC (permalink / raw)
To: pve-devel
Previously, `FaIconData` extended `IconData`, but starting from
`v11.0.0`, `FaIconData` no longer implements `IconData` to prevent
rendering issues and to anticipate `IconData` being marked `final`
in an upcoming Flutter release, which will prevent subtyping outside
of its library.
Due to this change, the `Icon` widget can no longer directly accept
`FontAwesomeIcons`. To fix this, replace the `Icon` widget with
`FaIcon` wherever `FontAwesomeIcons` is used.
Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
lib/pages/main_layout_slim.dart | 4 +-
lib/utils/renderers.dart | 5 +--
lib/widgets/pve_action_card_widget.dart | 17 +++++++++
lib/widgets/pve_file_selector_widget.dart | 6 +--
lib/widgets/pve_guest_backup_widget.dart | 2 +-
lib/widgets/pve_guest_migrate_widget.dart | 4 +-
lib/widgets/pve_guest_os_selector_widget.dart | 4 +-
| 4 +-
lib/widgets/pve_lxc_overview.dart | 32 +++++-----------
lib/widgets/pve_node_overview.dart | 6 +--
lib/widgets/pve_qemu_overview.dart | 38 +++++++------------
.../pve_qemu_power_settings_widget.dart | 4 +-
pubspec.lock | 4 +-
pubspec.yaml | 2 +-
14 files changed, 63 insertions(+), 69 deletions(-)
diff --git a/lib/pages/main_layout_slim.dart b/lib/pages/main_layout_slim.dart
index 4229ef4..c8ab607 100644
--- a/lib/pages/main_layout_slim.dart
+++ b/lib/pages/main_layout_slim.dart
@@ -861,11 +861,11 @@ class AppBarFilterIconButton extends StatelessWidget {
builder: (context, state) {
return IconButton(
icon: rBloc.isFiltered
- ? const Icon(
+ ? const FaIcon(
FontAwesomeIcons.filter,
color: Colors.black,
)
- : const Icon(
+ : const FaIcon(
FontAwesomeIcons.filter,
color: Colors.grey,
),
diff --git a/lib/utils/renderers.dart b/lib/utils/renderers.dart
index b139a87..5c73539 100644
--- a/lib/utils/renderers.dart
+++ b/lib/utils/renderers.dart
@@ -35,13 +35,12 @@ class Renderers {
return Icons.storage;
case "qemu":
return Icons.desktop_windows;
-
case "lxc":
- return FontAwesomeIcons.cube;
+ return FontAwesomeIcons.cube.data;
case "storage":
return (shared ?? false)
? Icons.folder_shared
- : FontAwesomeIcons.database;
+ : FontAwesomeIcons.database.data;
case "pool":
return Icons.label;
default:
diff --git a/lib/widgets/pve_action_card_widget.dart b/lib/widgets/pve_action_card_widget.dart
index 019a584..9fca232 100644
--- a/lib/widgets/pve_action_card_widget.dart
+++ b/lib/widgets/pve_action_card_widget.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
+import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class ActionCard extends StatelessWidget {
final Function? onTap;
@@ -14,6 +15,22 @@ class ActionCard extends StatelessWidget {
this.color,
});
+ factory ActionCard.withIcon(String title, IconData icon, Function onTap) {
+ return ActionCard(
+ title: title,
+ icon: Icon(icon, size: 55, color: Colors.white24),
+ onTap: onTap,
+ );
+ }
+
+ factory ActionCard.withFaIcon(String title, FaIconData icon, Function onTap) {
+ return ActionCard(
+ title: title,
+ icon: FaIcon(icon, size: 55, color: Colors.white24),
+ onTap: onTap,
+ );
+ }
+
@override
Widget build(BuildContext context) {
return Card(
diff --git a/lib/widgets/pve_file_selector_widget.dart b/lib/widgets/pve_file_selector_widget.dart
index 59964dd..1722e50 100644
--- a/lib/widgets/pve_file_selector_widget.dart
+++ b/lib/widgets/pve_file_selector_widget.dart
@@ -373,7 +373,7 @@ class FileSelectorContentView extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
- Icon(
+ FaIcon(
getContentIcon(content![index].content),
color: Theme.of(context).colorScheme.secondary,
),
@@ -401,7 +401,7 @@ class FileSelectorContentView extends StatelessWidget {
itemCount: content!.length,
itemBuilder: (context, index) => Card(
child: ListTile(
- leading: Icon(
+ leading: FaIcon(
getContentIcon(content![index].content),
color: Theme.of(context).colorScheme.secondary,
),
@@ -418,7 +418,7 @@ class FileSelectorContentView extends StatelessWidget {
);
}
- IconData getContentIcon(PveStorageContentType? content) {
+ FaIconData getContentIcon(PveStorageContentType? content) {
switch (content) {
case PveStorageContentType.iso:
return FontAwesomeIcons.compactDisc;
diff --git a/lib/widgets/pve_guest_backup_widget.dart b/lib/widgets/pve_guest_backup_widget.dart
index 4966e9d..119348b 100644
--- a/lib/widgets/pve_guest_backup_widget.dart
+++ b/lib/widgets/pve_guest_backup_widget.dart
@@ -205,7 +205,7 @@ class PveGuestBackupContent extends StatelessWidget {
itemCount: content!.length,
itemBuilder: (context, index) => Card(
child: ListTile(
- leading: Icon(
+ leading: FaIcon(
FontAwesomeIcons.floppyDisk,
color: Theme.of(context).colorScheme.onSurface,
),
diff --git a/lib/widgets/pve_guest_migrate_widget.dart b/lib/widgets/pve_guest_migrate_widget.dart
index cb6cd38..c65f6fe 100644
--- a/lib/widgets/pve_guest_migrate_widget.dart
+++ b/lib/widgets/pve_guest_migrate_widget.dart
@@ -55,7 +55,7 @@ class PveGuestMigrate extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListTile(
- leading: const Icon(FontAwesomeIcons.globe),
+ leading: const FaIcon(FontAwesomeIcons.globe),
title: Text(
'Mode',
style: TextStyle(color: colorScheme.onPrimary),
@@ -68,7 +68,7 @@ class PveGuestMigrate extends StatelessWidget {
),
),
ListTile(
- leading: const Icon(FontAwesomeIcons.mapPin),
+ leading: const FaIcon(FontAwesomeIcons.mapPin),
title: Text(
'Source',
style: TextStyle(color: colorScheme.onPrimary),
diff --git a/lib/widgets/pve_guest_os_selector_widget.dart b/lib/widgets/pve_guest_os_selector_widget.dart
index 2b3bd82..3a89143 100644
--- a/lib/widgets/pve_guest_os_selector_widget.dart
+++ b/lib/widgets/pve_guest_os_selector_widget.dart
@@ -40,11 +40,11 @@ class PveGuestOsSelector extends StatelessWidget {
Widget getIcon(String? osGroup) {
if (osGroup == "Microsoft Windows") {
- return const Icon(FontAwesomeIcons.windows);
+ return const FaIcon(FontAwesomeIcons.windows);
}
if (osGroup == "Linux") {
- return const Icon(FontAwesomeIcons.linux);
+ return const FaIcon(FontAwesomeIcons.linux);
}
return Text(osGroup!);
--git a/lib/widgets/pve_guest_overview_header.dart b/lib/widgets/pve_guest_overview_header.dart
index e4b5756..addb888 100644
--- a/lib/widgets/pve_guest_overview_header.dart
+++ b/lib/widgets/pve_guest_overview_header.dart
@@ -122,7 +122,7 @@ class PveGuestOverviewHeader extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
children: <Widget>[
- Icon(
+ FaIcon(
FontAwesomeIcons.heartPulse,
color: haError ? Colors.red : Colors.green[400],
),
@@ -219,7 +219,7 @@ class _PveGuestHeaderRRDPageViewState extends State<PveGuestHeaderRRDPageView> {
subtitle: Renderers.formatSize(rrdData.last.mem ?? 0),
data: rrdData.where((e) => e.mem != null).map(
(e) => Point(e.time!.millisecondsSinceEpoch, e.mem!)),
- icon: Icon(FontAwesomeIcons.memory, color: fgColor),
+ icon: FaIcon(FontAwesomeIcons.memory, color: fgColor),
bottomRight: pageIndicator,
dataRenderer: (data) => Renderers.formatSize(data),
),
diff --git a/lib/widgets/pve_lxc_overview.dart b/lib/widgets/pve_lxc_overview.dart
index 78ad853..7caa5cf 100644
--- a/lib/widgets/pve_lxc_overview.dart
+++ b/lib/widgets/pve_lxc_overview.dart
@@ -38,18 +38,6 @@ class PveLxcOverview extends StatelessWidget {
static final routeName = RegExp(r"\/nodes\/(\S+)\/lxc\/(\d+)");
final String guestID;
- ActionCard createActionCard(String title, IconData icon, Function onTap) {
- return ActionCard(
- icon: Icon(
- icon,
- size: 55,
- color: Colors.white24,
- ),
- title: title,
- onTap: onTap,
- );
- }
-
const PveLxcOverview({super.key, required this.guestID});
@override
Widget build(BuildContext context) {
@@ -139,13 +127,13 @@ class PveLxcOverview extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (!(status?.template ?? false))
- createActionCard(
+ ActionCard.withIcon(
'Power Settings',
Icons.power_settings_new,
() => showPowerMenuBottomSheet(
context, lxcBloc)),
if (!(status?.template ?? false))
- createActionCard(
+ ActionCard.withIcon(
'Console',
Icons.queue_play_next,
() => showConsoleMenuBottomSheet(
@@ -154,7 +142,7 @@ class PveLxcOverview extends StatelessWidget {
guestID,
state.nodeID,
'lxc')),
- createActionCard(
+ ActionCard.withIcon(
'Options',
Icons.settings,
() => Navigator.of(context)
@@ -164,7 +152,7 @@ class PveLxcOverview extends StatelessWidget {
),
fullscreenDialog: true))),
if (!resourceBloc.latestState.isStandalone)
- createActionCard(
+ ActionCard.withFaIcon(
'Migrate',
FontAwesomeIcons.paperPlane,
() => Navigator.of(context).push(
@@ -172,7 +160,7 @@ class PveLxcOverview extends StatelessWidget {
guestID,
state.nodeID,
resourceBloc.apiClient!))),
- createActionCard(
+ ActionCard.withFaIcon(
'Backup',
FontAwesomeIcons.floppyDisk,
() => Navigator.of(context).push(
@@ -193,7 +181,7 @@ class PveLxcOverview extends StatelessWidget {
),
children: <Widget>[
ListTile(
- leading: const Icon(FontAwesomeIcons.memory),
+ leading: const FaIcon(FontAwesomeIcons.memory),
title: Text('${config.memory}'),
subtitle: const Text('Memory'),
dense: true,
@@ -211,7 +199,7 @@ class PveLxcOverview extends StatelessWidget {
dense: true,
),
ListTile(
- leading: const Icon(FontAwesomeIcons.hardDrive),
+ leading: const FaIcon(FontAwesomeIcons.hardDrive),
dense: true,
title: Text('${config.rootfs}'),
),
@@ -229,7 +217,7 @@ class PveLxcOverview extends StatelessWidget {
for (var net in config.net!)
ListTile(
leading:
- const Icon(FontAwesomeIcons.ethernet),
+ const FaIcon(FontAwesomeIcons.ethernet),
dense: true,
title: Text(net),
),
@@ -244,14 +232,14 @@ class PveLxcOverview extends StatelessWidget {
),
children: <Widget>[
ListTile(
- leading: const Icon(FontAwesomeIcons.globe),
+ leading: const FaIcon(FontAwesomeIcons.globe),
dense: true,
title: Text(
config.searchdomain ?? 'Use host settings'),
subtitle: const Text('DNS Domain'),
),
ListTile(
- leading: const Icon(
+ leading: const FaIcon(
FontAwesomeIcons.magnifyingGlass),
dense: true,
title: Text(
diff --git a/lib/widgets/pve_node_overview.dart b/lib/widgets/pve_node_overview.dart
index 7236cf4..092bb54 100644
--- a/lib/widgets/pve_node_overview.dart
+++ b/lib/widgets/pve_node_overview.dart
@@ -115,7 +115,7 @@ class PveNodeOverview extends StatelessWidget {
data: rrd.map((e) => Point(
e.time!.millisecondsSinceEpoch,
e.memused ?? 0)),
- icon: Icon(FontAwesomeIcons.memory,
+ icon: FaIcon(FontAwesomeIcons.memory,
color: fgColor),
bottomRight: pageIndicator,
dataRenderer: (data) =>
@@ -259,7 +259,7 @@ class PveNodeOverview extends StatelessWidget {
child: ListTile(
title: const Text('HD space (root)'),
subtitle: ProxmoxCapacityIndicator(
- icon: Icon(
+ icon: FaIcon(
FontAwesomeIcons.solidHardDrive,
color: Colors.blueGrey[300],
),
@@ -385,7 +385,7 @@ class PveNodeOverview extends StatelessWidget {
.map(
(d) => ListTile(
dense: true,
- leading: Icon(FontAwesomeIcons.solidHardDrive,
+ leading: FaIcon(FontAwesomeIcons.solidHardDrive,
color: state.isDiskHealthy(d)
? Colors.grey
: Colors.red),
diff --git a/lib/widgets/pve_qemu_overview.dart b/lib/widgets/pve_qemu_overview.dart
index 3fb25ba..12e3b30 100644
--- a/lib/widgets/pve_qemu_overview.dart
+++ b/lib/widgets/pve_qemu_overview.dart
@@ -40,18 +40,6 @@ class PveQemuOverview extends StatelessWidget {
const PveQemuOverview({super.key, required this.guestID});
- ActionCard createActionCard(String title, IconData icon, Function onTap) {
- return ActionCard(
- icon: Icon(
- icon,
- size: 55,
- color: Colors.white24,
- ),
- title: title,
- onTap: onTap,
- );
- }
-
@override
Widget build(BuildContext context) {
final bloc = Provider.of<PveQemuOverviewBloc>(context);
@@ -140,13 +128,13 @@ class PveQemuOverview extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (!(status?.template ?? false))
- createActionCard(
+ ActionCard.withIcon(
'Power Settings',
Icons.power_settings_new,
() =>
showPowerMenuBottomSheet(context, bloc)),
if (!(status?.template ?? false))
- createActionCard(
+ ActionCard.withIcon(
'Console',
Icons.queue_play_next,
() => showConsoleMenuBottomSheet(
@@ -157,19 +145,19 @@ class PveQemuOverview extends StatelessWidget {
'qemu',
allowSpice: status?.spice ?? false,
)),
- createActionCard(
+ ActionCard.withIcon(
'Options',
Icons.settings,
() => Navigator.of(context)
.push(_createOptionsRoute(bloc))),
if (!rBloc.latestState.isStandalone)
- createActionCard(
+ ActionCard.withFaIcon(
'Migrate',
FontAwesomeIcons.paperPlane,
() => Navigator.of(context).push(
_createMigrationRoute(guestID,
state.nodeID, bloc.apiClient))),
- createActionCard(
+ ActionCard.withFaIcon(
'Backup',
FontAwesomeIcons.floppyDisk,
() => Navigator.of(context).push(
@@ -191,7 +179,7 @@ class PveQemuOverview extends StatelessWidget {
),
children: [
ListTile(
- leading: const Icon(FontAwesomeIcons.memory),
+ leading: const FaIcon(FontAwesomeIcons.memory),
title: Text('${config.memory}'),
subtitle: const Text('Memory'),
dense: true,
@@ -204,20 +192,20 @@ class PveQemuOverview extends StatelessWidget {
dense: true,
),
ListTile(
- leading: const Icon(FontAwesomeIcons.microchip),
+ leading: const FaIcon(FontAwesomeIcons.microchip),
title: Text(
config.bios?.name ?? 'Default (SeaBIOS)'),
subtitle: const Text('BIOS'),
dense: true,
),
ListTile(
- leading: const Icon(FontAwesomeIcons.gears),
+ leading: const FaIcon(FontAwesomeIcons.gears),
dense: true,
title: Text(config.machine ?? 'Default (i440fx)'),
subtitle: const Text('Machine Type'),
),
ListTile(
- leading: const Icon(FontAwesomeIcons.database),
+ leading: const FaIcon(FontAwesomeIcons.database),
title: Text(
config.scsihw?.name ?? 'Default (i440fx)'),
subtitle: const Text('SCSI Controller'),
@@ -226,21 +214,23 @@ class PveQemuOverview extends StatelessWidget {
for (var ide in config.ide!)
ListTile(
leading:
- const Icon(FontAwesomeIcons.compactDisc),
+ const FaIcon(FontAwesomeIcons.compactDisc),
title: Text(ide),
subtitle: const Text('CD/DVD Drive'),
dense: true,
),
for (var scsi in config.scsi!)
ListTile(
- leading: const Icon(FontAwesomeIcons.hardDrive),
+ leading:
+ const FaIcon(FontAwesomeIcons.hardDrive),
title: Text(scsi),
subtitle: const Text('Hard Disk'),
dense: true,
),
for (var net in config.net!)
ListTile(
- leading: const Icon(FontAwesomeIcons.ethernet),
+ leading:
+ const FaIcon(FontAwesomeIcons.ethernet),
dense: true,
subtitle: const Text('Network Device'),
title: Text(net),
diff --git a/lib/widgets/pve_qemu_power_settings_widget.dart b/lib/widgets/pve_qemu_power_settings_widget.dart
index b4c3c0a..84c3b83 100644
--- a/lib/widgets/pve_qemu_power_settings_widget.dart
+++ b/lib/widgets/pve_qemu_power_settings_widget.dart
@@ -86,7 +86,7 @@ class PveQemuPowerSettings extends StatelessWidget {
context, PveClusterResourceAction.suspend, bloc),
),
ListTile(
- leading: const Icon(FontAwesomeIcons.download),
+ leading: const FaIcon(FontAwesomeIcons.download),
title: const Text(
"Hibernate",
style: TextStyle(fontWeight: FontWeight.bold),
@@ -106,7 +106,7 @@ class PveQemuPowerSettings extends StatelessWidget {
context, PveClusterResourceAction.stop, bloc),
),
ListTile(
- leading: const Icon(FontAwesomeIcons.bolt),
+ leading: const FaIcon(FontAwesomeIcons.bolt),
title: const Text(
"Reset",
style: TextStyle(fontWeight: FontWeight.bold),
diff --git a/pubspec.lock b/pubspec.lock
index ecaab97..def499d 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -324,10 +324,10 @@ packages:
dependency: "direct main"
description:
name: font_awesome_flutter
- sha256: b9011df3a1fa02993630b8fb83526368cf2206a711259830325bab2f1d2a4eb0
+ sha256: "09dcde8ab90ffae1a7d65ff2ef96fc62a17ad9d0ce7c127b317ded676b0d5935"
url: "https://pub.dev"
source: hosted
- version: "10.12.0"
+ version: "11.0.0"
glob:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index e15d57b..04c56a4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -30,7 +30,7 @@ dependencies:
path: ^1.8.0
provider: ^6.0.1
meta: ^1.1.7
- font_awesome_flutter: ^10.0.0
+ font_awesome_flutter: ^11.0.0
url_launcher: ^6.0.17
intl: ^0.20.1
path_provider: ^2.0.8
--
2.50.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH pve_flutter_frontend 3/4] fix: migrate to UIScene lifecycle for iOS 26+ compatibility
2026-04-10 15:09 [PATCH proxmox{_login_manager,_dart_api_client}/pve_flutter_frontend 0/7] upgrade dependencies based on flutter v3.41 and migrate deprecated members Shan Shaji
2026-04-10 15:09 ` [PATCH pve_flutter_frontend 1/4] chore: upgrade dependencies based on flutter v3.41 Shan Shaji
2026-04-10 15:09 ` [PATCH pve_flutter_frontend 2/4] fix: breaking changes due to the upgrade of font_awesome_flutter to v11 Shan Shaji
@ 2026-04-10 15:09 ` Shan Shaji
2026-04-10 15:09 ` [PATCH pve_flutter_frontend 4/4] chore: use latest ndkVersion from flutter Shan Shaji
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Shan Shaji @ 2026-04-10 15:09 UTC (permalink / raw)
To: pve-devel
Apple has announced that starting with the SDK following iOS 26 [0], all
UIKit-based apps must adopt the UIScene lifecycle. Apps that continue to
rely solely on the legacy AppDelegate lifecycle for UI initialization
will fail to launch.
The plugin registration was happening inside the
`application:didFinishLaunchingWithOptions` method. To accommodate the
new app launch sequence moved the initialization to
`didInitializeImplicitFlutterEngine` [1]
This change also shifts window management away from the AppDelegate.
Attempting to access the window object there may return nil, as the
UI lifecycle is now handled by the new SceneDelegate.
To fix the issue [2][3]:
* Defined a new SceneDelegate class (subclassing FlutterSceneDelegate).
* Registered the SceneDelegate within the Info.plist under the
`UIApplicationSceneManifest`.
* Migrated all file sharing logic and method channel setups from the
`AppDelegate` to the `SceneDelegate` within the
scene(_:willConnectTo:options:) method.
- [0] https://docs.flutter.dev/release/breaking-changes/uiscenedelegate#background
- [1] https://docs.flutter.dev/release/breaking-changes/uiscenedelegate#migrate-appdelegate
- [2] https://docs.flutter.dev/release/breaking-changes/uiscenedelegate#bespoke-flutterviewcontroller-usage
- [3] https://developer.apple.com/documentation/uikit/specifying-the-scenes-your-app-supports#Configure-the-details-for-each-scene
Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
ios/Runner.xcodeproj/project.pbxproj | 4 ++
ios/Runner/AppDelegate.swift | 53 ++-----------------------
ios/Runner/Info.plist | 21 ++++++++++
ios/Runner/SceneDelegate.swift | 59 ++++++++++++++++++++++++++++
4 files changed, 88 insertions(+), 49 deletions(-)
create mode 100644 ios/Runner/SceneDelegate.swift
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index a9d4fd5..8bf8472 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 1B87D59D2F89184000623BAC /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B87D59C2F89183C00623BAC /* SceneDelegate.swift */; };
1BE02BA02EB5028D00B28B3B /* AppIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = 1BE02B9F2EB5028D00B28B3B /* AppIcon.icon */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
@@ -47,6 +48,7 @@
022505048A677FEA7AF056D1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
+ 1B87D59C2F89183C00623BAC /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
1BE02B9F2EB5028D00B28B3B /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = AppIcon.icon; sourceTree = "<group>"; };
3158807C4D56CFC909080136 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
@@ -145,6 +147,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
+ 1B87D59C2F89183C00623BAC /* SceneDelegate.swift */,
1BE02B9F2EB5028D00B28B3B /* AppIcon.icon */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
@@ -382,6 +385,7 @@
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ 1B87D59D2F89184000623BAC /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index 428976f..bb1afce 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -2,60 +2,15 @@ import Flutter
import UIKit
@main
-@objc class AppDelegate: FlutterAppDelegate {
+@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
- let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
- let channel: FlutterMethodChannel = FlutterMethodChannel(
- name: "com.proxmox.app.pve_flutter_frontend/filesharing",
- binaryMessenger: controller.binaryMessenger)
-
- channel.setMethodCallHandler({
- [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
-
- guard call.method == "shareFile" else {
- result(FlutterMethodNotImplemented)
- return
- }
-
- let arguments = call.arguments as? [String: Any]
- let path = arguments?["path"] as? String
- let type = arguments?["type"] as? String
-
- if let filePath = path, let _ = type {
- self?.shareFile(atPath: filePath, from: controller, result: result)
- } else {
- result(FlutterError(code: "FileNotFoundException", message: "File not found", details: nil))
- }
- })
-
- GeneratedPluginRegistrant.register(with: self)
-
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
-
- private func shareFile(atPath path: String, from controller: UIViewController, result: @escaping FlutterResult) {
- let fileURL = URL(fileURLWithPath: path)
- let activityVC = UIActivityViewController(
- activityItems: [fileURL],
- applicationActivities: nil,
- )
-
- // To avoid crashing in iPad
- if let popover = activityVC.popoverPresentationController {
- popover.sourceView = controller.view
- popover.sourceRect = CGRect(
- x: controller.view.bounds.midX,
- y: controller.view.bounds.midY,
- width: 0,
- height: 0,
- )
- }
-
- controller.present(activityVC, animated: true) {
- result(nil)
- }
+
+ func didInitializeImplicitFlutterEngine(_ engineBridge: any FlutterImplicitEngineBridge) {
+ GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
}
}
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index a5587ed..9ba026f 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -2,6 +2,27 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+ <key>UIApplicationSceneManifest</key>
+ <dict>
+ <key>UIApplicationSupportsMultipleScenes</key>
+ <false/>
+ <key>UISceneConfigurations</key>
+ <dict>
+ <key>UIWindowSceneSessionRoleApplication</key>
+ <array>
+ <dict>
+ <key>UISceneClassName</key>
+ <string>UIWindowScene</string>
+ <key>UISceneDelegateClassName</key>
+ <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
+ <key>UISceneConfigurationName</key>
+ <string>flutter</string>
+ <key>UISceneStoryboardFile</key>
+ <string>Main</string>
+ </dict>
+ </array>
+ </dict>
+ </dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
diff --git a/ios/Runner/SceneDelegate.swift b/ios/Runner/SceneDelegate.swift
new file mode 100644
index 0000000..2ceca09
--- /dev/null
+++ b/ios/Runner/SceneDelegate.swift
@@ -0,0 +1,59 @@
+import Flutter
+import UIKit
+
+class SceneDelegate: FlutterSceneDelegate {
+ override func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
+ super.scene(scene, willConnectTo: session, options: connectionOptions)
+
+ guard let window = self.window,
+ let controller = window.rootViewController as? FlutterViewController else {
+ return
+ }
+
+ let channel: FlutterMethodChannel = FlutterMethodChannel(
+ name: "com.proxmox.app.pve_flutter_frontend/filesharing",
+ binaryMessenger: controller.binaryMessenger)
+
+ channel.setMethodCallHandler({
+ [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
+
+ guard call.method == "shareFile" else {
+ result(FlutterMethodNotImplemented)
+ return
+ }
+
+ let arguments = call.arguments as? [String: Any]
+ let path = arguments?["path"] as? String
+ let type = arguments?["type"] as? String
+
+ if let filePath = path, let _ = type {
+ self?.shareFile(atPath: filePath, from: controller, result: result)
+ } else {
+ result(FlutterError(code: "FileNotFoundException", message: "File not found", details: nil))
+ }
+ })
+ }
+
+ private func shareFile(atPath path: String, from controller: UIViewController, result: @escaping FlutterResult) {
+ let fileURL = URL(fileURLWithPath: path)
+ let activityVC = UIActivityViewController(
+ activityItems: [fileURL],
+ applicationActivities: nil,
+ )
+
+ // To avoid crashing in iPad
+ if let popover = activityVC.popoverPresentationController {
+ popover.sourceView = controller.view
+ popover.sourceRect = CGRect(
+ x: controller.view.bounds.midX,
+ y: controller.view.bounds.midY,
+ width: 0,
+ height: 0,
+ )
+ }
+
+ controller.present(activityVC, animated: true) {
+ result(nil)
+ }
+ }
+}
--
2.50.1
^ permalink raw reply [flat|nested] 8+ messages in thread