Skip to content

Commit 0081f3c

Browse files
v1: Add --no-cdn option (full offline support) to flet build, flet run and flet publish (#5257)
* Include replaced controls to remove_controls * Add --no-cdn and --no-wasm options to CLI * Update pyproject_toml.py * SafeArea conflicting props renaming * AuthorizationService and stub for Pyodide * Slider value is optional * Fix Slider assertions * fixed Gradient bug * OutlinedButton: deleted `text` property * --no-cdn finished * Fix web job * Fixed getWidgetStateProperty() * Another fix of getWidgetStateProperty() --------- Co-authored-by: InesaFitsner <inesa@appveyor.com>
1 parent 39a33a7 commit 0081f3c

File tree

27 files changed

+641
-454
lines changed

27 files changed

+641
-454
lines changed

.appveyor.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ environment:
6969
job_group: build_flet
7070
job_depends_on: build_flet_package
7171
PYODIDE_URL: https://github.com/pyodide/pyodide/releases/download/0.27.5/pyodide-core-0.27.5.tar.bz2
72+
PYODIDE_CDN_URL: https://cdn.jsdelivr.net/pyodide/v0.27.5/full
7273
APPVEYOR_BUILD_WORKER_IMAGE: ubuntu2004
7374

7475
- job_name: Test Python 3.10
@@ -388,6 +389,8 @@ for:
388389
- ls "$(dirname "$(command -v flutter)")/cache/flutter_web_sdk/flutter_js"
389390
- cp "$(dirname "$(command -v flutter)")/cache/flutter_web_sdk/flutter_js/flutter.js.map" $flet_sdk_root/packages/flet-web/src/flet_web/web
390391
- curl -L $PYODIDE_URL | tar -xj -C "$flet_sdk_root/packages/flet-web/src/flet_web/web"
392+
- curl -L $PYODIDE_CDN_URL/packaging-24.2-py3-none-any.whl -o "$flet_sdk_root/packages/flet-web/src/flet_web/web/pyodide/packaging-24.2-py3-none-any.whl"
393+
- curl -L $PYODIDE_CDN_URL/micropip-0.8.0-py3-none-any.whl -o "$flet_sdk_root/packages/flet-web/src/flet_web/web/pyodide/micropip-0.8.0-py3-none-any.whl"
391394
- popd
392395
- tar -czvf client/build/flet-web.tar.gz -C client/build/web .
393396

@@ -466,4 +469,4 @@ for:
466469
auth_token: $(GITHUB_TOKEN)
467470
release: $(APPVEYOR_REPO_TAG_NAME)
468471
on:
469-
APPVEYOR_REPO_TAG: true
472+
APPVEYOR_REPO_TAG: true

client/web/flutter_bootstrap.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ var config = {};
66
if (webRenderer != "auto") {
77
config.renderer = webRenderer;
88
}
9+
if (globalThis.canvasKitBaseUrl) {
10+
config.canvasKitBaseUrl = globalThis.canvasKitBaseUrl;
11+
}
912
_flutter.loader.load({
1013
config: config,
1114
serviceWorkerSettings: {
@@ -22,4 +25,4 @@ _flutter.loader.load({
2225
loading.remove();
2326
}, 200);
2427
}
25-
});
28+
});

client/web/index.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,21 @@
2828
<script>
2929
var webRenderer = "auto";
3030
var useColorEmoji = false;
31+
var appPackageUrl = "app.tar.gz";
32+
var noCdn = false;
3133
</script>
3234

3335
<!-- webRenderer -->
3436
<!-- useColorEmoji -->
3537
<!-- pyodideCode -->
38+
<!-- noCdn -->
39+
40+
<script>
41+
if (noCdn) {
42+
var canvasKitBaseUrl = "/canvaskit/";
43+
var pyodideUrl = "/pyodide/pyodide.js";
44+
}
45+
</script>
3646

3747
<script src="python.js"></script>
3848
</head>
@@ -97,4 +107,4 @@
97107
</div>
98108
<script src="flutter_bootstrap.js" async></script>
99109
</body>
100-
</html>
110+
</html>

client/web/python-worker.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
self.pyodideUrl = null;
2+
self.appPackageUrl = null;
23
self.micropipIncludePre = false;
34
self.pythonModuleName = null;
45
self.documentUrl = null;
@@ -10,6 +11,7 @@ self.initPyodide = async function () {
1011
importScripts(self.pyodideUrl);
1112
self.pyodide = await loadPyodide();
1213
self.pyodide.registerJsModule("flet_js", flet_js);
14+
self.pyodide.globals.set("app_package_url", self.appPackageUrl);
1315
self.pyodide.globals.set("python_module_name", self.pythonModuleName);
1416
self.pyodide.globals.set("micropip_include_pre", self.micropipIncludePre);
1517
flet_js.documentUrl = documentUrl;
@@ -19,13 +21,19 @@ self.initPyodide = async function () {
1921
from pyodide.http import pyfetch
2022
2123
py_args = flet_js.args.to_py() if flet_js.args else None
22-
24+
25+
if "app_package_url" in py_args:
26+
app_package_url = py_args["app_package_url"]
27+
28+
if app_package_url is None:
29+
app_package_url = "assets/app/app.zip"
30+
2331
if "python_module_name" in py_args:
2432
python_module_name = py_args["python_module_name"]
25-
33+
2634
if python_module_name is None:
2735
python_module_name = "main"
28-
36+
2937
if "micropip_include_pre" in py_args:
3038
micropip_include_pre = py_args["micropip_include_pre"]
3139
@@ -37,18 +45,18 @@ self.initPyodide = async function () {
3745
3846
if "script" not in py_args:
3947
print("Downloading app archive")
40-
response = await pyfetch("assets/app/app.zip")
48+
response = await pyfetch(app_package_url)
4149
await response.unpack_archive()
4250
else:
4351
print("Saving script to a file")
4452
with open(f"{python_module_name}.py", "w") as f:
4553
f.write(py_args["script"]);
46-
54+
4755
pkgs_path = "__pypackages__"
4856
if os.path.exists(pkgs_path):
4957
print(f"Adding {pkgs_path} to sys.path")
5058
sys.path.insert(0, pkgs_path)
51-
59+
5260
if os.path.exists("requirements.txt"):
5361
with open("requirements.txt", "r") as f:
5462
deps = [line.rstrip() for line in f]
@@ -57,7 +65,7 @@ self.initPyodide = async function () {
5765
5866
if "dependencies" in py_args:
5967
await micropip.install(py_args["dependencies"], pre=micropip_include_pre)
60-
68+
6169
# Execute app
6270
runpy.run_module(python_module_name, run_name="__main__")
6371
`);
@@ -79,11 +87,12 @@ self.onmessage = async (event) => {
7987
self.pyodideUrl = event.data.pyodideUrl;
8088
self.flet_js.args = event.data.args;
8189
self.documentUrl = event.data.documentUrl;
90+
self.appPackageUrl = event.data.appPackageUrl;
8291
self.micropipIncludePre = event.data.micropipIncludePre;
8392
self.pythonModuleName = event.data.pythonModuleName;
8493
await self.initPyodide();
8594
} else {
8695
// message
8796
flet_js.send(event.data);
8897
}
89-
};
98+
};

client/web/python.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ globalThis.jsConnect = async function(appId, args, dartOnMessage) {
3333
pyodideUrl: globalThis.pyodideUrl ?? defaultPyodideUrl,
3434
args: args,
3535
documentUrl: _documentUrl,
36+
appPackageUrl: globalThis.appPackageUrl,
3637
micropipIncludePre: globalThis.micropipIncludePre,
3738
pythonModuleName: globalThis.pythonModuleName
3839
});
@@ -66,4 +67,4 @@ globalThis.jsDisconnect = async function(appId) {
6667
app.worker.onmessage = null;
6768
app.worker.onerror = null;
6869
}
69-
}
70+
}

packages/flet/lib/src/controls/safe_area.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ class SafeAreaControl extends StatelessWidget {
1717
debugPrint("SafeArea build: ${control.id}");
1818

1919
final safeArea = SafeArea(
20-
left: control.getBool("left", true)!,
21-
top: control.getBool("top", true)!,
22-
right: control.getBool("right", true)!,
23-
bottom: control.getBool("bottom", true)!,
20+
left: control.getBool("avoid_intrusions_left", true)!,
21+
top: control.getBool("avoid_intrusions_top", true)!,
22+
right: control.getBool("avoid_intrusions_right", true)!,
23+
bottom: control.getBool("avoid_intrusions_bottom", true)!,
2424
maintainBottomViewPadding:
2525
control.getBool("maintain_bottom_view_padding", false)!,
2626
minimum: control.getEdgeInsets("minimum_padding", EdgeInsets.zero)!,

packages/flet/lib/src/utils/gradient.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Gradient? parseGradient(dynamic value, ThemeData theme) {
1212
if (value == null) return null;
1313

1414
String type = value["type"];
15-
var colors = parseColors(theme, value["colors"]);
15+
var colors = parseColors(value["colors"], theme);
1616
var stops = parseGradientStops(value["stops"]);
1717
var rotation = parseRotation(value["rotation"]);
1818
if (type == "linear") {
@@ -123,6 +123,7 @@ Color lerpGradient(List<Color> colors, List<double> stops, double t) {
123123
}
124124
return colors.last;
125125
}
126+
126127
extension GradientParsers on Control {
127128
Gradient? getGradient(String propertyName, ThemeData theme) {
128129
return parseGradient(get(propertyName), theme);
@@ -145,4 +146,4 @@ extension GradientParsers on Control {
145146
[GradientRotation? defaultValue]) {
146147
return parseRotation(get(propertyName), defaultValue);
147148
}
148-
}
149+
}

packages/flet/lib/src/utils/material_state.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@ import 'package:flutter/material.dart';
44

55
import '../models/control.dart';
66

7-
WidgetStateProperty<T?>? getWidgetStateProperty<T>(dynamic value,
8-
T Function(dynamic) converterFromJson,
7+
WidgetStateProperty<T?>? getWidgetStateProperty<T>(
8+
dynamic value, T Function(dynamic) converterFromJson,
99
[T? defaultValue]) {
1010
if (value == null) return null;
1111
var j = value;
1212
if (j is! Map<dynamic, dynamic>) {
1313
j = {"default": j};
1414
}
15+
if (j.containsKey("")) {
16+
j["default"] = j.remove("");
17+
}
18+
if (!j.keys.every(
19+
(k) => k == "default" || WidgetState.values.any((v) => v.name == k))) {
20+
// wrap into another dict
21+
j = {"default": j};
22+
}
1523
return WidgetStateFromJSON(j, converterFromJson, defaultValue);
1624
}
1725

0 commit comments

Comments
 (0)