From 1a0771d65e694613478915b1645813a3c75ad706 Mon Sep 17 00:00:00 2001 From: basemosama Date: Sun, 29 Jun 2025 16:13:35 +0300 Subject: [PATCH 1/5] feat: Add web utilities for handling web-specific tasks and platform detection --- lib/playx_core.dart | 1 + lib/src/logger/playx_logger.dart | 1 + lib/src/utils/playx_platform.dart | 5 +- lib/src/utils/safe_convert.dart | 6 +- lib/src/utils/web/web_utils.dart | 2 + lib/src/utils/web/web_utils_stub.dart | 45 ++++++++++++++ lib/src/utils/web/web_utils_web.dart | 89 +++++++++++++++++++++++++++ pubspec.lock | 2 +- pubspec.yaml | 1 + 9 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 lib/src/utils/web/web_utils.dart create mode 100644 lib/src/utils/web/web_utils_stub.dart create mode 100644 lib/src/utils/web/web_utils_web.dart diff --git a/lib/playx_core.dart b/lib/playx_core.dart index c8f6b0c..4e29d19 100644 --- a/lib/playx_core.dart +++ b/lib/playx_core.dart @@ -32,6 +32,7 @@ export 'src/utils/mapper_utilities.dart'; export 'src/utils/playx_platform.dart'; export 'src/utils/safe_convert.dart'; export 'src/utils/safe_json_convert.dart'; +export 'src/utils/web/web_utils.dart'; export 'src/logger/base_logger.dart'; export 'src/logger/playx_logger.dart'; export 'src/logger/playx_logger_settings.dart'; diff --git a/lib/src/logger/playx_logger.dart b/lib/src/logger/playx_logger.dart index cd6da6e..04c7bea 100644 --- a/lib/src/logger/playx_logger.dart +++ b/lib/src/logger/playx_logger.dart @@ -40,6 +40,7 @@ class PlayxLogger { String? name, PlayxLoggerSettings? settings, bool setAsDefault = true, + }) { final logger = TalkerPlayxLogger( settings: settings ?? PlayxLoggerSettings(), name: name); diff --git a/lib/src/utils/playx_platform.dart b/lib/src/utils/playx_platform.dart index 2b38aa8..eeb0598 100644 --- a/lib/src/utils/playx_platform.dart +++ b/lib/src/utils/playx_platform.dart @@ -1,11 +1,14 @@ import 'package:flutter/foundation.dart' - show kIsWeb, TargetPlatform, defaultTargetPlatform; + show kIsWeb, TargetPlatform, defaultTargetPlatform, kIsWasm; /// Utility class for determining the current platform type and characteristics. class PlayxPlatform { /// Returns `true` if the platform is the web. static bool get isWeb => kIsWeb; + /// Returns `true` if the platform is WebAssembly. + static bool get isWasm => kIsWasm; + /// Returns `true` if the platform is Android. static bool get isAndroid => !isWeb && defaultTargetPlatform == TargetPlatform.android; diff --git a/lib/src/utils/safe_convert.dart b/lib/src/utils/safe_convert.dart index 003d167..f80ee15 100644 --- a/lib/src/utils/safe_convert.dart +++ b/lib/src/utils/safe_convert.dart @@ -10,8 +10,9 @@ int? toIntOrNull(dynamic value) { if (value is int) return value; if (value is double) return value.toInt(); if (value is bool) return value ? 1 : 0; - if (value is String) + if (value is String) { return int.tryParse(value) ?? double.tryParse(value)?.toInt(); + } return null; } @@ -69,12 +70,13 @@ double toDouble(dynamic value) => bool? toBoolOrNull(dynamic value) { if (value == null) return null; if (value is bool) return value; - if (value is num) + if (value is num) { return value == 1 ? true : value == 0 ? false : null; + } if (value is String) { final lower = value.toLowerCase(); if (lower == 'true') return true; diff --git a/lib/src/utils/web/web_utils.dart b/lib/src/utils/web/web_utils.dart new file mode 100644 index 0000000..d254dc7 --- /dev/null +++ b/lib/src/utils/web/web_utils.dart @@ -0,0 +1,2 @@ +export 'web_utils_stub.dart' + if (dart.library.html) 'web_utils_web.dart'; diff --git a/lib/src/utils/web/web_utils_stub.dart b/lib/src/utils/web/web_utils_stub.dart new file mode 100644 index 0000000..0588103 --- /dev/null +++ b/lib/src/utils/web/web_utils_stub.dart @@ -0,0 +1,45 @@ +import 'package:flutter/services.dart'; + +/// A stubbed version of [WebUtils] for non-web platforms (e.g. mobile, desktop). +/// +/// All methods are safe no-ops and will not affect the app outside the web environment. +class WebUtils { + const WebUtils._(); + + /// Stub: Does nothing on non-web platforms. + static void updateUrl(Uri uri) {} + + /// Stub: Does nothing on non-web platforms. + static void setBodyBackgroundColor(String colorHex) {} + + /// Stub: Sets only the app switcher title, as `document.title` is not supported. + static void setAppTitle({required String title,Color? primaryColor, bool webOnly = true, }) { + if(webOnly) { + return; + } + SystemChrome.setApplicationSwitcherDescription( + ApplicationSwitcherDescription(label: title, primaryColor: primaryColor?.toARGB32()), + ); + } + + /// Stub: Always returns `false` on non-web platforms. + static bool isFullScreen() => false; + + /// Stub: Does nothing on non-web platforms. + static void enterFullScreen() {} + + /// Stub: Does nothing on non-web platforms. + static void exitFullScreen() {} + + /// Stub: Does nothing on non-web platforms. + static void toggleFullScreen() {} + + /// Stub: Does nothing on non-web platforms. + static void reloadPage() {} + + /// Stub: Does nothing on non-web platforms. + static void openInNewTab(String url) {} + + /// Stub: Does nothing on non-web platforms. + static void updateQueryParameters(Map newParams) {} +} diff --git a/lib/src/utils/web/web_utils_web.dart b/lib/src/utils/web/web_utils_web.dart new file mode 100644 index 0000000..cb43ee0 --- /dev/null +++ b/lib/src/utils/web/web_utils_web.dart @@ -0,0 +1,89 @@ +import 'package:web/web.dart'; +import 'package:flutter/services.dart'; + +/// A collection of static helper methods for performing common web-related tasks. +/// Only works when running on the web. +class WebUtils { + const WebUtils._(); + + /// Updates the browser's URL without navigating or reloading the page. + /// + /// This uses the HTML5 History API to replace the current URL in the address bar. + static void updateUrl(Uri uri) { + window.history.replaceState(null, '', uri.toString()); + } + + + /// Sets the background color of the `` element directly via inline style. + /// + /// This overrides any background-color set by CSS classes. + static void setBodyBackgroundColor(String colorHex) { + final body = document.body; + if (body != null) { + body.style.backgroundColor = colorHex; + } + } + + + /// Sets the title of the web tab and application switcher. + /// + /// This affects browser tab titles and some OS-level application switchers. + static void setAppTitle(String title) { + document.title = title; + SystemChrome.setApplicationSwitcherDescription( + ApplicationSwitcherDescription(label: title), + ); + } + + /// Checks if the browser is currently in fullscreen mode. + /// + /// Returns `true` if fullscreen mode is active, `false` otherwise. + static bool isFullScreen() { + return document.fullscreenElement != null; + } + + /// Requests the browser to enter fullscreen mode. + /// + /// This may require a user gesture (like a button press) to succeed. + static void enterFullScreen() { + document.documentElement?.requestFullscreen(); + } + + /// Requests the browser to exit fullscreen mode if it's currently active. + static void exitFullScreen() { + document.exitFullscreen(); + } + + /// Toggles fullscreen mode: enters if not in fullscreen, exits if already in fullscreen. + /// + /// This is useful for toggling fullscreen with a single button or gesture. + static void toggleFullScreen() { + if (isFullScreen()) { + exitFullScreen(); + } else { + enterFullScreen(); + } + } + + /// Reloads the current web page. + static void reloadPage() { + window.location.reload(); + } + + /// Opens a new browser tab or window with the given [url]. + /// + /// Uses `target = "_blank"` by default. + static void openInNewTab(String url) { + window.open(url, '_blank'); + } + + /// Updates only the query parameters in the browser URL without navigating. + /// + /// Preserves the current path and hash. + static void updateQueryParameters(Map newParams) { + final currentUri = Uri.parse(window.location.href); + final newUri = currentUri.replace(queryParameters: newParams); + window.history.replaceState(null, '', newUri.toString()); + } + +} diff --git a/pubspec.lock b/pubspec.lock index a50d13a..cc03ebf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -446,7 +446,7 @@ packages: source: hosted version: "15.0.0" web: - dependency: transitive + dependency: "direct main" description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" diff --git a/pubspec.yaml b/pubspec.yaml index bd5b0d1..e3183f6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: get_it: ^8.0.3 worker_manager: ^7.2.6 talker_logger: ^4.9.1 + web: ^1.1.1 dev_dependencies: flutter_test: From 50f4d87877e8469b2fce42d9ff2d2dcb7e2eebf4 Mon Sep 17 00:00:00 2001 From: basemosama Date: Sun, 29 Jun 2025 16:13:53 +0300 Subject: [PATCH 2/5] feat: Update CHANGELOG for v0.7.1 with new features and dependency updates --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa02402..912ae49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.7.1 + +- Updated dependencies. +- Added `isWasm` to `PlayxPlatform` to detect if the app is running in a WebAssembly environment. +- Introduced `WebUtils`, a new utility class providing common browser-side features for web apps: + - Update the browser URL and query parameters without navigation. + - Control fullscreen mode (enter, exit, toggle). + - Set the browser tab title and application switcher label. + - Change `` background color directly or by CSS class. + - Open links in new tabs. + - Reload the page. + + ## v0.7.0 > Note: This release has breaking changes. From 9b3d8179851adbe4b7daf4626416b470da63e2e4 Mon Sep 17 00:00:00 2001 From: basemosama Date: Sun, 29 Jun 2025 16:14:36 +0300 Subject: [PATCH 3/5] refactor: Code cleanup --- lib/src/extensions/date_time_extensions.dart | 4 ++-- lib/src/logger/playx_logger.dart | 1 - lib/src/utils/web/web_utils.dart | 3 +-- lib/src/utils/web/web_utils_stub.dart | 11 ++++++++--- lib/src/utils/web/web_utils_web.dart | 3 --- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/src/extensions/date_time_extensions.dart b/lib/src/extensions/date_time_extensions.dart index 97d402f..638a254 100644 --- a/lib/src/extensions/date_time_extensions.dart +++ b/lib/src/extensions/date_time_extensions.dart @@ -7,7 +7,7 @@ enum Weekday { saturday, sunday; - static fromDate(DateTime date) { + static Weekday fromDate(DateTime date) { return Weekday.values[date.weekday - 1]; } } @@ -26,7 +26,7 @@ enum Month { november, december; - static fromDate(DateTime date) { + static Month fromDate(DateTime date) { return Month.values[date.month - 1]; } } diff --git a/lib/src/logger/playx_logger.dart b/lib/src/logger/playx_logger.dart index 04c7bea..cd6da6e 100644 --- a/lib/src/logger/playx_logger.dart +++ b/lib/src/logger/playx_logger.dart @@ -40,7 +40,6 @@ class PlayxLogger { String? name, PlayxLoggerSettings? settings, bool setAsDefault = true, - }) { final logger = TalkerPlayxLogger( settings: settings ?? PlayxLoggerSettings(), name: name); diff --git a/lib/src/utils/web/web_utils.dart b/lib/src/utils/web/web_utils.dart index d254dc7..41edcc1 100644 --- a/lib/src/utils/web/web_utils.dart +++ b/lib/src/utils/web/web_utils.dart @@ -1,2 +1 @@ -export 'web_utils_stub.dart' - if (dart.library.html) 'web_utils_web.dart'; +export 'web_utils_stub.dart' if (dart.library.html) 'web_utils_web.dart'; diff --git a/lib/src/utils/web/web_utils_stub.dart b/lib/src/utils/web/web_utils_stub.dart index 0588103..9133201 100644 --- a/lib/src/utils/web/web_utils_stub.dart +++ b/lib/src/utils/web/web_utils_stub.dart @@ -13,12 +13,17 @@ class WebUtils { static void setBodyBackgroundColor(String colorHex) {} /// Stub: Sets only the app switcher title, as `document.title` is not supported. - static void setAppTitle({required String title,Color? primaryColor, bool webOnly = true, }) { - if(webOnly) { + static void setAppTitle({ + required String title, + Color? primaryColor, + bool webOnly = true, + }) { + if (webOnly) { return; } SystemChrome.setApplicationSwitcherDescription( - ApplicationSwitcherDescription(label: title, primaryColor: primaryColor?.toARGB32()), + ApplicationSwitcherDescription( + label: title, primaryColor: primaryColor?.toARGB32()), ); } diff --git a/lib/src/utils/web/web_utils_web.dart b/lib/src/utils/web/web_utils_web.dart index cb43ee0..3ab9bf4 100644 --- a/lib/src/utils/web/web_utils_web.dart +++ b/lib/src/utils/web/web_utils_web.dart @@ -13,7 +13,6 @@ class WebUtils { window.history.replaceState(null, '', uri.toString()); } - /// Sets the background color of the `` element directly via inline style. /// /// This overrides any background-color set by CSS classes. @@ -24,7 +23,6 @@ class WebUtils { } } - /// Sets the title of the web tab and application switcher. /// /// This affects browser tab titles and some OS-level application switchers. @@ -85,5 +83,4 @@ class WebUtils { final newUri = currentUri.replace(queryParameters: newParams); window.history.replaceState(null, '', newUri.toString()); } - } From 62b3963238f7a9acc7d92655bbc3d11ca201d902 Mon Sep 17 00:00:00 2001 From: basemosama Date: Sun, 29 Jun 2025 16:20:17 +0300 Subject: [PATCH 4/5] feat: Update Flutter version matrix in GitHub Actions workflow to use 'latest' --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 954af07..b783775 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - flutter: [ 3.24.0, stable] + flutter: [ 3.24.0, latest] steps: - uses: actions/checkout@v2 - uses: subosito/flutter-action@v2 From 7ef58180e31c441f4017731d25e42bad57f56030 Mon Sep 17 00:00:00 2001 From: basemosama Date: Sun, 29 Jun 2025 16:29:28 +0300 Subject: [PATCH 5/5] feat: Update Flutter version matrix in GitHub Actions workflow to use 'latest' --- .github/workflows/build.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b783775..7a1967e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,11 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - flutter: [ 3.24.0, latest] + include: + - flutter-version: 3.24.0 + flutter-channel: stable + - flutter-version: latest + flutter-channel: stable steps: - uses: actions/checkout@v2 - uses: subosito/flutter-action@v2