Skip to content

Preparing Flet v0.28.3 release #5306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Flet changelog

## 0.28.3

* New: Multiple subscribers can subscribe to a published topic by `send_all_on_topic` ([#5303](https://github.com/flet-dev/flet/issues/5303))
* Fixed: Local Images Not Rendering in Android App using Flet 0.27.6 ([#5198](https://github.com/flet-dev/flet/issues/5198))
* Fixed: FilePicker.save_file() opens blank gray screen in APK build (works fine in VS) ([#5301](https://github.com/flet-dev/flet/issues/5301))
* Fixed: Routing / Navigation broken since flet 0.28.2 ([#5302](https://github.com/flet-dev/flet/issues/5302))

## 0.28.2

* Fixed missing imports in `__init__.py` ([#5292](https://github.com/flet-dev/flet/pull/5292)).
Expand Down
2 changes: 1 addition & 1 deletion ci/whats-new.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
$milestone = 15
$milestone = 17

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Expand Down
5 changes: 5 additions & 0 deletions packages/flet/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 0.28.3

* Fixed: Local Images Not Rendering in Android App using Flet 0.27.6 ([#5198](https://github.com/flet-dev/flet/issues/5198))
* Fixed: FilePicker.save_file() opens blank gray screen in APK build (works fine in VS) ([#5301](https://github.com/flet-dev/flet/issues/5301))

# 0.28.2

* Fixed missing imports in `__init__.py` ([#5292](https://github.com/flet-dev/flet/pull/5292)).
Expand Down
18 changes: 11 additions & 7 deletions packages/flet/lib/src/controls/file_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,17 @@ class _FilePickerControlState extends State<FilePickerControl>
else if (state?.toLowerCase() == "savefile" && !kIsWeb) {
FilePicker.platform
.saveFile(
dialogTitle: dialogTitle,
fileName: fileName,
initialDirectory: initialDirectory,
lockParentWindow: true,
type: fileType,
allowedExtensions: allowedExtensions,
)
dialogTitle: dialogTitle,
fileName: fileName != null || !isiOSPlatform()
? fileName
: "new-file",
initialDirectory: initialDirectory,
lockParentWindow: true,
type: fileType,
allowedExtensions: allowedExtensions,
bytes: isAndroidPlatform() || isiOSPlatform()
? Uint8List(0)
: null)
.then((result) {
debugPrint("saveFile() completed");
_path = result;
Expand Down
3 changes: 1 addition & 2 deletions packages/flet/lib/src/utils/uri.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ Uri getAssetUri(Uri pageUri, String assetPath) {
scheme: pageUri.scheme,
host: pageUri.host,
port: pageUri.port,
path: pageUri.path +
(assetPath.startsWith("/") ? assetPath.substring(1) : assetPath));
pathSegments: [...pageUri.pathSegments, ...assetPath.split("/")]);
}

Uri getBaseUri(Uri pageUri) {
Expand Down
4 changes: 2 additions & 2 deletions packages/flet/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: flet
description: Write entire Flutter app in Python or add server-driven UI experience into existing Flutter app.
homepage: https://flet.dev
repository: https://github.com/flet-dev/flet/packages/flet
version: 0.28.2
version: 0.28.3

# This package supports all platforms listed below.
platforms:
Expand Down Expand Up @@ -34,7 +34,7 @@ dependencies:
flutter_highlight: ^0.7.0
highlight: ^0.7.0
markdown: ^7.2.2
file_picker: ^8.1.3
file_picker: ^10.1.9
shared_preferences: ^2.3.2
flutter_svg: ^2.0.13
window_to_front: ^0.0.3
Expand Down
5 changes: 0 additions & 5 deletions sdk/python/packages/flet/src/flet/core/file_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
from flet.core.ref import Ref
from flet.core.types import OptionalEventCallable

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal


class FilePickerState(Enum):
PICK_FILES = "pickFiles"
Expand Down
12 changes: 6 additions & 6 deletions sdk/python/packages/flet/src/flet/core/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,9 @@ def page(cls) -> "Page":
try:
from flet.auth.authorization import Authorization
from flet.auth.oauth_provider import OAuthProvider
except ImportError as e:
except ImportError:

class OAuthProvider:
...
class OAuthProvider: ...

class Authorization:
def __init__(
Expand All @@ -119,8 +118,7 @@ def __init__(
fetch_user: bool,
fetch_groups: bool,
scope: Optional[List[str]] = None,
):
...
): ...


AT = TypeVar("AT", bound=Authorization)
Expand Down Expand Up @@ -624,7 +622,9 @@ def convert_route_change_event(e):
self._add_event_handler("route_change", self.__on_route_change.get_handler())

def convert_view_pop_event(e):
return ViewPopEvent(view=cast(View, self.get_control(e.data)))
# e.data contains route name
view = next((v for v in self.views if v.route == e.data), None)
return ViewPopEvent(view=view) if view in self.views else None

self.__on_view_pop = EventHandler(convert_view_pop_event)
self._add_event_handler("view_pop", self.__on_view_pop.get_handler())
Expand Down
44 changes: 30 additions & 14 deletions sdk/python/packages/flet/src/flet/core/pubsub/pubsub_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,49 +22,57 @@ def __init__(
self.__executor = executor
self.__lock = threading.Lock() if not is_pyodide() else NopeLock()
self.__subscribers: Dict[
str, Union[Callable, Callable[..., Awaitable[Any]]]
str, set[Union[Callable, Callable[..., Awaitable[Any]]]]
] = {} # key: session_id, value: handler
self.__topic_subscribers: Dict[
str, Dict[str, Union[Callable, Callable[..., Awaitable[Any]]]]
str, Dict[str, set[Union[Callable, Callable[..., Awaitable[Any]]]]]
] = {} # key: topic, value: dict[session_id, handler]
self.__subscriber_topics: Dict[
str, Dict[str, Union[Callable, Callable[..., Awaitable[Any]]]]
str, Dict[str, set[Union[Callable, Callable[..., Awaitable[Any]]]]]
] = {} # key: session_id, value: dict[topic, handler]

def send_all(self, message: Any):
logger.debug(f"pubsub.send_all({message})")
with self.__lock:
for handler in self.__subscribers.values():
self.__send(handler, [message])
for handlers in self.__subscribers.values():
for handler in handlers:
self.__send(handler, [message])

def send_all_on_topic(self, topic: str, message: Any):
logger.debug(f"pubsub.send_all_on_topic({topic}, {message})")
with self.__lock:
if topic in self.__topic_subscribers:
for handler in self.__topic_subscribers[topic].values():
self.__send(handler, [topic, message])
for handlers in self.__topic_subscribers[topic].values():
for handler in handlers:
self.__send(handler, [topic, message])

def send_others(self, except_session_id: str, message: Any):
logger.debug(f"pubsub.send_others({except_session_id}, {message})")
with self.__lock:
for session_id, handler in self.__subscribers.items():
for session_id, handlers in self.__subscribers.items():
if except_session_id != session_id:
self.__send(handler, [message])
for handler in handlers:
self.__send(handler, [message])

def send_others_on_topic(self, except_session_id: str, topic: str, message: Any):
logger.debug(
f"pubsub.send_others_on_topic({except_session_id}, {topic}, {message})"
)
with self.__lock:
if topic in self.__topic_subscribers:
for session_id, handler in self.__topic_subscribers[topic].items():
for session_id, handlers in self.__topic_subscribers[topic].items():
if except_session_id != session_id:
self.__send(handler, [topic, message])
for handler in handlers:
self.__send(handler, [topic, message])

def subscribe(self, session_id: str, handler: Callable):
logger.debug(f"pubsub.subscribe({session_id})")
with self.__lock:
self.__subscribers[session_id] = handler
handlers = self.__subscribers.get(session_id)
if handlers is None:
handlers = set()
self.__subscribers[session_id] = handlers
handlers.add(handler)

def subscribe_topic(
self,
Expand All @@ -86,12 +94,20 @@ def __subscribe_topic(
if topic_subscribers is None:
topic_subscribers = {}
self.__topic_subscribers[topic] = topic_subscribers
topic_subscribers[session_id] = handler
handlers = topic_subscribers.get(session_id)
if handlers is None:
handlers = set()
topic_subscribers[session_id] = handlers
handlers.add(handler)
subscriber_topics = self.__subscriber_topics.get(session_id)
if subscriber_topics is None:
subscriber_topics = {}
self.__subscriber_topics[session_id] = subscriber_topics
subscriber_topics[topic] = handler
handlers = subscriber_topics.get(topic)
if handlers is None:
handlers = set()
subscriber_topics[topic] = handlers
handlers.add(handler)

def unsubscribe(self, session_id: str):
logger.debug(f"pubsub.unsubscribe({session_id})")
Expand Down