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: 5 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
flutter: [ 3.24.0, stable]
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
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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 `<body>` background color directly or by CSS class.
- Open links in new tabs.
- Reload the page.


## v0.7.0

> Note: This release has breaking changes.
Expand Down
1 change: 1 addition & 0 deletions lib/playx_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
4 changes: 2 additions & 2 deletions lib/src/extensions/date_time_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ enum Weekday {
saturday,
sunday;

static fromDate(DateTime date) {
static Weekday fromDate(DateTime date) {
return Weekday.values[date.weekday - 1];
}
}
Expand All @@ -26,7 +26,7 @@ enum Month {
november,
december;

static fromDate(DateTime date) {
static Month fromDate(DateTime date) {
return Month.values[date.month - 1];
}
}
Expand Down
5 changes: 4 additions & 1 deletion lib/src/utils/playx_platform.dart
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
6 changes: 4 additions & 2 deletions lib/src/utils/safe_convert.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions lib/src/utils/web/web_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'web_utils_stub.dart' if (dart.library.html) 'web_utils_web.dart';
50 changes: 50 additions & 0 deletions lib/src/utils/web/web_utils_stub.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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<String, String> newParams) {}
}
86 changes: 86 additions & 0 deletions lib/src/utils/web/web_utils_web.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
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 `<body>` 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<String, String> newParams) {
final currentUri = Uri.parse(window.location.href);
final newUri = currentUri.replace(queryParameters: newParams);
window.history.replaceState(null, '', newUri.toString());
}
}
2 changes: 1 addition & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ packages:
source: hosted
version: "15.0.0"
web:
dependency: transitive
dependency: "direct main"
description:
name: web
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading