Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* Multi-version bundled CPython support in `flet build` and `flet publish`. Pick the runtime your app ships with via the new `--python-version` flag (3.12 / 3.13 / 3.14), or let it be derived from `[project].requires-python` in your `pyproject.toml`; defaults to the latest supported stable (currently 3.14). The matching CPython-standalone build, Pyodide release (0.27.7 / 0.29.4 / 314.0.0a2), and Emscripten wheel platform tag are all resolved from a central registry. Adding a future pre-release CPython line (e.g. 3.15 beta) is a one-row append with `prerelease=True` — opt-in only via an explicit `--python-version 3.15` or `requires-python = "==3.15.*"`, never the auto-resolved default. Requires `serious_python` >= 2.0.0, now pinned in the `flet build` template. See the new [Choosing a Python version](https://flet.dev/docs/publish#choosing-a-python-version) docs section ([#6577](https://github.com/flet-dev/flet/pull/6577)) by @FeodorFitsner.
* Add `flet clean` command that deletes the `build` directory of a Flet app — the Flutter bootstrap project, cached artifacts, and generated output — in a single step ([#6233](https://github.com/flet-dev/flet/issues/6233)) by @ndonkoHenri.
* Add `compression_quality` to `FilePicker.pick_files()` for selecting the image compression quality used by supported platforms ([#6573](https://github.com/flet-dev/flet/pull/6573)) by @ndonkoHenri.

### Improvements

Expand All @@ -25,6 +26,11 @@
* Fix `flet build` failing on Windows when a dependency is pulled in via `[tool.flet.<platform>].dev_packages` (or any local-path install): the rewritten `<pkg> @ file://<path>` URL now uses `Path.as_uri()`, producing the correct `file:///D:/...` three-slash form instead of `file://D:\...`, which pip on Windows parsed as a UNC path and aborted with `OSError: [Errno 2] No such file or directory: '\\\\D:\\a\\...'` ([#6577](https://github.com/flet-dev/flet/pull/6577)) by @FeodorFitsner.
* Fix `flet build apk` failing at `mergeDebugNativeLibs` with `N files found with path 'lib/<abi>/libc++_shared.so'` when an app combines `serious_python_android` with another Flutter plugin that also bundles the NDK C++ runtime ([#6570](https://github.com/flet-dev/flet/issues/6570), [#6571](https://github.com/flet-dev/flet/pull/6571)) by @ndonkoHenri.
* Specify `handler` signatures in `subscribe` and `subscribe_topic` methods of `PubSubClient` for better type checking ([#6549](https://github.com/flet-dev/flet/pull/6564)) by @Iaw4tch
* Fix `FilePicker.pick_files()` on web for slow network shares or slow machines: pass `cancel_upload_on_window_blur=False` to prevent valid file selections from being reported as cancelled when the browser window loses focus during file picking ([#771](https://github.com/flet-dev/flet/issues/771), [#6573](https://github.com/flet-dev/flet/pull/6573)) by @ndonkoHenri.

### Documentation

* Improve `FilePicker.save_file()` documentation: on desktop, passing `src_bytes` writes those bytes to the selected file ([#6573](https://github.com/flet-dev/flet/pull/6573)) by @ndonkoHenri.

## 0.85.3

Expand Down
13 changes: 9 additions & 4 deletions packages/flet/lib/src/services/file_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class FilePickerService extends FletService {
?.map((e) => e.toString())
.toList();
var withData = parseBool(args["with_data"], false)!;
var cancelUploadOnWindowBlur =
parseBool(args["cancel_upload_on_window_blur"], true)!;
var compressionQuality = parseInt(args["compression_quality"], 0)!;
var srcBytes = args["src_bytes"];
Comment thread
ndonkoHenri marked this conversation as resolved.

if (allowedExtensions != null && allowedExtensions.isNotEmpty) {
Expand All @@ -48,15 +51,17 @@ class FilePickerService extends FletService {
uploadFiles(files, control.backend.pageUri);
}
case "pick_files":
_files = (await FilePicker.platform.pickFiles(
_files = (await FilePicker.pickFiles(
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
lockParentWindow: true,
type: fileType,
allowedExtensions: allowedExtensions,
compressionQuality: compressionQuality,
allowMultiple: args["allow_multiple"],
withData: withData,
withReadStream: !withData))
withReadStream: !withData,
cancelUploadOnWindowBlur: cancelUploadOnWindowBlur))
?.files;
return _files != null
? _files!.asMap().entries.map((file) {
Expand All @@ -79,7 +84,7 @@ class FilePickerService extends FletService {
throw Exception(
"\"file_name\" is required when saving a file on Web.");
}
return await FilePicker.platform.saveFile(
return await FilePicker.saveFile(
dialogTitle: dialogTitle,
fileName: args["file_name"] != null || !isIOSMobile()
? args["file_name"]
Expand All @@ -93,7 +98,7 @@ class FilePickerService extends FletService {
if (kIsWeb) {
throw Exception("Get Directory Path dialog is not supported on web.");
}
return await FilePicker.platform.getDirectoryPath(
return await FilePicker.getDirectoryPath(
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
lockParentWindow: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/flet/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dependencies:
cupertino_icons: ^1.0.6
device_info_plus: ^12.3.0
equatable: ^2.0.3
file_picker: ^10.3.10
file_picker: ^11.0.2
flutter_highlight: ^0.7.0
flutter_markdown_plus: ^1.0.7
flutter_markdown_plus_latex: ^1.0.5
Expand Down
29 changes: 23 additions & 6 deletions sdk/python/packages/flet/src/flet/controls/services/file_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ async def save_file(
name to save a file.

Note:
- On desktop this method only opens a dialog for the user to select
a location and file name, and returns the chosen path. The file
itself is not created or saved.
- On desktop, this method opens a dialog for the user to select a
location and file name. If `src_bytes` is provided, those bytes
are written to the selected file.

Args:
dialog_title: The title of the dialog window.
Expand All @@ -270,8 +270,7 @@ async def save_file(
src_bytes: The contents of a file. Must be provided in web,
iOS or Android modes.
allowed_extensions: The allowed file extensions. Has effect only if
`file_type` is
:attr:`flet.FilePickerFileType.CUSTOM`.
`file_type` is :attr:`flet.FilePickerFileType.CUSTOM`.

Raises:
ValueError: If `src_bytes` is not provided, when called in web mode,
Expand Down Expand Up @@ -308,6 +307,8 @@ async def pick_files(
allowed_extensions: Optional[list[str]] = None,
allow_multiple: bool = False,
with_data: bool = False,
compression_quality: int = 0,
cancel_upload_on_window_blur: bool = True,
) -> list[FilePickerFile]:
"""
Opens a pick file dialog.
Expand All @@ -322,13 +323,27 @@ async def pick_files(
file_type: The file types allowed to be selected.
allow_multiple: Allow the selection of multiple files at once.
with_data: Read selected file contents into
:attr:`flet.FilePickerFile.bytes`.
:attr:`~flet.FilePickerFile.bytes`.
compression_quality: Image compression quality from `0` to `100`.
`0` disables compression.
cancel_upload_on_window_blur: Web-only. Whether to treat browser
window blur as a cancelled selection. Set to `False` to avoid
losing valid selections on slow networks or slow machines.
allowed_extensions: The allowed file extensions. Has effect only if
`file_type` is :attr:`flet.FilePickerFileType.CUSTOM`.

Returns:
A list of selected files.

Raises:
ValueError: If `compression_quality` is not between
`0` and `100` inclusive.
"""
if not (0 <= compression_quality <= 100):
raise ValueError(
"compression_quality must be between 0 and 100 inclusive, "
f"got {compression_quality}."
)
files = await self._invoke_method(
"pick_files",
{
Expand All @@ -338,6 +353,8 @@ async def pick_files(
"allowed_extensions": allowed_extensions,
"allow_multiple": allow_multiple,
"with_data": with_data,
"compression_quality": compression_quality,
"cancel_upload_on_window_blur": cancel_upload_on_window_blur,
Comment thread
ndonkoHenri marked this conversation as resolved.
},
timeout=3600,
)
Expand Down
108 changes: 77 additions & 31 deletions sdk/python/packages/flet/src/flet/controls/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,114 +944,160 @@ class DeviceOrientation(Enum):
class FloatingActionButtonLocation(Enum):
"""
Defines a position for the :class:`~flet.FloatingActionButton`.

See [FloatingActionButtonLocation](https://api.flutter.dev/flutter/material/FloatingActionButtonLocation-class.html)
from Flutter documentation for placement location examples.
""" # noqa: E501

CENTER_DOCKED = "centerDocked"
"""
Centers the floating action button over the bottom navigation bar so its center
aligns with the bar's top edge.
Centered :class:`~flet.FloatingActionButton`, floating over a bottom navigation \
control so the button's center lines up with the top of that control.

This is typically used with a bottom navigation bar or bottom app bar that can
visually accommodate the overlapping button.
Not typically useful for apps without a bottom navigation control.
"""

CENTER_FLOAT = "centerFloat"
"""
Centers the floating action button near the bottom of the screen.
Centered :class:`~flet.FloatingActionButton`, floating at the bottom of the \
screen.

Use :attr:`MINI_CENTER_FLOAT` for mini buttons.
"""

CENTER_TOP = "centerTop"
"""
Centers the floating action button over the boundary between the app bar and the
body.
Centered :class:`~flet.FloatingActionButton`, floating over the transition \
between the :class:`~flet.AppBar` and the page body.

Not typically useful for apps without a top :class:`~flet.AppBar`.
"""

END_CONTAINED = "endContained"
"""
Aligns the floating action button to the end side and positions it so it lines up
with the vertical center of the bottom navigation bar.
End-aligned :class:`~flet.FloatingActionButton`, floating over a bottom \
navigation control so the button lines up with that control's center.

Not typically useful for apps with a :class:`~flet.NavigationBar` or a \
non-Material 3 :class:`~flet.BottomAppBar`.
"""

END_DOCKED = "endDocked"
"""
Aligns the floating action button to the end side and docks it over the bottom
navigation bar so its center aligns with the bar's top edge.
End-aligned :class:`~flet.FloatingActionButton`, floating over a bottom \
navigation control so the button's center lines up with the top of that control.

Not typically useful for apps without a bottom navigation control.
"""

END_FLOAT = "endFloat"
"""
Aligns the floating action button to the end side near the bottom of the screen.
End-aligned :class:`~flet.FloatingActionButton`, floating at the bottom of the \
screen.

This is the default alignment in Material apps. Use :attr:`MINI_END_FLOAT` for \
mini buttons.
"""

END_TOP = "endTop"
"""
Aligns the floating action button to the end side over the boundary between the
app bar and the body.
End-aligned :class:`~flet.FloatingActionButton`, floating over the transition \
between the :class:`~flet.AppBar` and the page body.

Not typically useful for apps without a top :class:`~flet.AppBar`.
"""

MINI_CENTER_DOCKED = "miniCenterDocked"
"""
Like :attr:`CENTER_DOCKED`, but intended for a mini floating action button.
Centered mini :class:`~flet.FloatingActionButton`, floating over a bottom \
navigation control so the button's center lines up with the top of that control.

Intended for use with mini buttons.
"""

MINI_CENTER_FLOAT = "miniCenterFloat"
"""
Like :attr:`CENTER_FLOAT`, but optimized for a mini floating action button.
Centered mini :class:`~flet.FloatingActionButton`, floating at the bottom of the \
screen.

Intended for use with mini buttons.
"""

MINI_CENTER_TOP = "miniCenterTop"
"""
Like :attr:`CENTER_TOP`, but intended for a mini floating action button.
Centered mini :class:`~flet.FloatingActionButton`, floating over the transition \
between the :class:`~flet.AppBar` and the page body.

Intended for use with mini buttons.
"""

MINI_END_DOCKED = "miniEndDocked"
"""
Like :attr:`END_DOCKED`, but intended for a mini floating action button.
End-aligned mini :class:`~flet.FloatingActionButton`, floating over a bottom \
navigation control so the button's center lines up with the top of that control.

Intended for use with mini buttons.
"""

MINI_END_FLOAT = "miniEndFloat"
"""
Like :attr:`END_FLOAT`, but optimized for a mini floating action button.
End-aligned mini :class:`~flet.FloatingActionButton`, floating at the bottom of \
the screen.

Intended for use with mini buttons.
"""

MINI_END_TOP = "miniEndTop"
"""
Like :attr:`END_TOP`, but intended for a mini floating action button.
End-aligned mini :class:`~flet.FloatingActionButton`, floating over the \
transition between the :class:`~flet.AppBar` and the page body.

Intended for use with mini buttons.
"""

MINI_START_DOCKED = "miniStartDocked"
"""
Like :attr:`START_DOCKED`, but intended for a mini floating action button.
Start-aligned mini :class:`~flet.FloatingActionButton`, floating over a bottom \
navigation control so the button's center lines up with the top of that control.

Intended for use with mini buttons.
"""

MINI_START_FLOAT = "miniStartFloat"
"""
Like :attr:`START_FLOAT`, but optimized for a mini floating action button.
Start-aligned mini :class:`~flet.FloatingActionButton`, floating at the bottom \
of the screen.

Intended for use with mini buttons.
"""

MINI_START_TOP = "miniStartTop"
"""
Like :attr:`START_TOP`, but intended for a mini floating action button.
Start-aligned mini :class:`~flet.FloatingActionButton`, floating over the \
transition between the :class:`~flet.AppBar` and the page body.

Intended for use with mini buttons.
"""

START_DOCKED = "startDocked"
"""
Aligns the floating action button to the start side and docks it over the bottom
navigation bar so its center aligns with the bar's top edge.
Start-aligned :class:`~flet.FloatingActionButton`, floating over a bottom \
navigation control so the button's center lines up with the top of that control.

Not typically useful for apps without a bottom navigation control.
"""

START_FLOAT = "startFloat"
"""
Aligns the floating action button to the start side near the bottom of the screen.
Start-aligned :class:`~flet.FloatingActionButton`, floating at the bottom of the \
screen.

Use :attr:`MINI_START_FLOAT` for mini buttons.
"""

START_TOP = "startTop"
"""
Aligns the floating action button to the start side over the boundary between the
app bar and the body.
Start-aligned :class:`~flet.FloatingActionButton`, floating over the transition \
between the :class:`~flet.AppBar` and the page body.

Not typically useful for apps without a top :class:`~flet.AppBar`.
"""


Expand Down
Loading