Skip to content

Commit 6590f1f

Browse files
feat: page.get_device_info() to get device informations (#5672)
* initial commit * export missing classes in __all__ * fix typos * documentation * unindent subclasses in docstring * Use from_dict for device info instantiation Replaced direct class instantiation with the from_dict utility for device info objects in Page.get_device_info. This improves consistency and handles dictionary-to-object conversion more robustly. * add "Returns" to docstring * Add JS interop support to msgpack encoder Introduces JSAny type and conditional JS interop import for Dart, enabling serialization of JS interop objects in FletMsgpackEncoder. Updates protocol.py to handle new ext type code for JSAny. Also comments out unused HTML view sections and updates PyPI cleanup version pattern. --------- Co-authored-by: Feodor Fitsner <[email protected]>
1 parent dbcb55f commit 6590f1f

26 files changed

+1123
-28
lines changed

.github/scripts/clean-pypi.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# set PYPI_CLEANUP_PASSWORD with pypi.org password
22

3-
VER="0\.70\.0\.dev(?!5399)"
3+
VER="0\.70\.0\.dev(?!6176)"
44
uv tool install pypi-cleanup
55
uvx pypi-cleanup -u flet -p flet -y -r $VER --do-it
66
uvx pypi-cleanup -u flet -p flet-cli -y -r $VER --do-it

client/pubspec.lock

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,10 @@ packages:
181181
dependency: transitive
182182
description:
183183
name: device_info_plus
184-
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
184+
sha256: "49413c8ca514dea7633e8def233b25efdf83ec8522955cc2c0e3ad802927e7c6"
185185
url: "https://pub.dev"
186186
source: hosted
187-
version: "11.5.0"
187+
version: "12.1.0"
188188
device_info_plus_platform_interface:
189189
dependency: transitive
190190
description:
@@ -277,7 +277,7 @@ packages:
277277
description:
278278
path: "src/flutter/flet_ads"
279279
ref: main
280-
resolved-ref: aa05773138be06e69353e2a223bd23c51b36dd3f
280+
resolved-ref: c320d40add2fd2d46f5f82029a4f259936308847
281281
url: "https://github.com/flet-dev/flet-ads.git"
282282
source: git
283283
version: "0.2.0"
@@ -286,7 +286,7 @@ packages:
286286
description:
287287
path: "src/flutter/flet_audio"
288288
ref: main
289-
resolved-ref: "06fb901f133fab54e603f8039bc9a1d707d19068"
289+
resolved-ref: "1e629a501a87b0c2c0a9956cf49552dc01efcbe5"
290290
url: "https://github.com/flet-dev/flet-audio.git"
291291
source: git
292292
version: "0.2.0"
@@ -295,7 +295,7 @@ packages:
295295
description:
296296
path: "src/flutter/flet_audio_recorder"
297297
ref: main
298-
resolved-ref: "62a1934a34514e92617f4e090b53828474f5969e"
298+
resolved-ref: e29cd51dec917fdb8b9e03d7bf4a71cb2f75217b
299299
url: "https://github.com/flet-dev/flet-audio-recorder.git"
300300
source: git
301301
version: "0.2.0"
@@ -304,7 +304,7 @@ packages:
304304
description:
305305
path: "src/flutter/flet_charts"
306306
ref: main
307-
resolved-ref: d1303e03a6e39ab72ea888eb22219ba330704313
307+
resolved-ref: "6902aeb244d676cb85f14268126df9c4fe7af084"
308308
url: "https://github.com/flet-dev/flet-charts.git"
309309
source: git
310310
version: "0.2.0"
@@ -313,7 +313,7 @@ packages:
313313
description:
314314
path: "src/flutter/flet_datatable2"
315315
ref: main
316-
resolved-ref: bf6af9c7a9c1962c36512ff5ab48eec9f14ef81a
316+
resolved-ref: b53fba432acf42e01505acba5898bc47d7d25797
317317
url: "https://github.com/flet-dev/flet-datatable2.git"
318318
source: git
319319
version: "0.1.0"
@@ -322,7 +322,7 @@ packages:
322322
description:
323323
path: "src/flutter/flet_flashlight"
324324
ref: main
325-
resolved-ref: def30504c3ed6786dc2a1fdb4f18b226a284a7d2
325+
resolved-ref: "0862f0324f4a0c1a405b2c1dc23e3857175b36cc"
326326
url: "https://github.com/flet-dev/flet-flashlight.git"
327327
source: git
328328
version: "0.2.0"
@@ -331,7 +331,7 @@ packages:
331331
description:
332332
path: "src/flutter/flet_geolocator"
333333
ref: main
334-
resolved-ref: "25efd0a9d15f23bf284912814a131388f8de9ec4"
334+
resolved-ref: "8381f3605b09eec6cbf02c44abb8216aaedf22b2"
335335
url: "https://github.com/flet-dev/flet-geolocator.git"
336336
source: git
337337
version: "0.25.2"
@@ -340,7 +340,7 @@ packages:
340340
description:
341341
path: "src/flutter/flet_lottie"
342342
ref: main
343-
resolved-ref: "5187fcf6bcb37f4bfa59cad127f6444d40cdb48c"
343+
resolved-ref: c9e8db9bab3ae0054de4e7b3fcb3fe282f6d8ee6
344344
url: "https://github.com/flet-dev/flet-lottie.git"
345345
source: git
346346
version: "0.2.0"
@@ -349,7 +349,7 @@ packages:
349349
description:
350350
path: "src/flutter/flet_map"
351351
ref: main
352-
resolved-ref: d79ebf24ebad208a543b73a7f7511cd4da1d7ea9
352+
resolved-ref: "3575ca7dc80251e6b0ac7648ff2620adb84db412"
353353
url: "https://github.com/flet-dev/flet-map.git"
354354
source: git
355355
version: "0.2.0"
@@ -358,7 +358,7 @@ packages:
358358
description:
359359
path: "src/flutter/flet_permission_handler"
360360
ref: main
361-
resolved-ref: dbd04f183b8452a5247f2807007cc40a2381a172
361+
resolved-ref: "6c9ac6c2c5608e00603c542a13e545ffba637398"
362362
url: "https://github.com/flet-dev/flet-permission-handler.git"
363363
source: git
364364
version: "0.2.0"
@@ -367,7 +367,7 @@ packages:
367367
description:
368368
path: "src/flutter/flet_rive"
369369
ref: main
370-
resolved-ref: "6d78b068940afa5126fc38374ea326e710d43862"
370+
resolved-ref: "6c9164f842e2d2b7ef27f09ab3bec163b63f6ac8"
371371
url: "https://github.com/flet-dev/flet-rive.git"
372372
source: git
373373
version: "0.2.0"
@@ -376,7 +376,7 @@ packages:
376376
description:
377377
path: "src/flutter/flet_video"
378378
ref: main
379-
resolved-ref: abeea4e9a3a2864299743726b26d5a245a4389d6
379+
resolved-ref: "9292cab1b40ce5ef81e9012421c05ce03d910133"
380380
url: "https://github.com/flet-dev/flet-video.git"
381381
source: git
382382
version: "0.2.0"
@@ -385,7 +385,7 @@ packages:
385385
description:
386386
path: "src/flutter/flet_webview"
387387
ref: main
388-
resolved-ref: cb3d07bfb84ae1b51be25388ca04c03a9dafd7f3
388+
resolved-ref: "4ae806ad9019a9d3883d1c0c88e30ba61aacb696"
389389
url: "https://github.com/flet-dev/flet-webview.git"
390390
source: git
391391
version: "0.2.0"

client/web/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@
138138
</div>
139139
<script src="flutter_bootstrap.js" async></script>
140140

141-
<h1>View 1</h1>
141+
<!-- <h1>View 1</h1>
142142
<div id="view-1" style="display: flex; justify-content: center;"></div>
143143
<h1>View 2</h1>
144-
<div id="view-2"></div>
144+
<div id="view-2"></div> -->
145145
</body>
146146
</html>

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import '../routing/route_parser.dart';
2020
import '../routing/route_state.dart';
2121
import '../routing/router_delegate.dart';
2222
import '../services/service_registry.dart';
23+
import '../utils/device_info.dart';
2324
import '../utils/locale.dart';
2425
import '../utils/numbers.dart';
2526
import '../utils/platform_utils_web.dart'
@@ -180,6 +181,8 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
180181

181182
case "push_route":
182183
_routeState.route = args["route"];
184+
case "get_device_info":
185+
return await getDeviceInfo();
183186

184187
default:
185188
throw Exception("Unknown Page method: $name");
@@ -390,7 +393,7 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
390393
var newLightTheme = control.getTheme("theme", context, Brightness.light);
391394
var newDarkTheme = control.getString("dark_theme") == null
392395
? control.getTheme("theme", context, Brightness.dark)
393-
: parseTheme(control.get("dark_theme"), context, Brightness.dark);
396+
: control.getTheme("dark_theme", context, Brightness.dark);
394397

395398
var lightTheme = control.get("_lightTheme");
396399
if (lightTheme == null || newLightTheme != lightTheme) {
@@ -407,7 +410,7 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
407410
var cupertinoTheme = themeMode == ThemeMode.light ||
408411
((themeMode == null || themeMode == ThemeMode.system) &&
409412
brightness == Brightness.light)
410-
? parseCupertinoTheme(control.get("theme"), context, Brightness.light)
413+
? control.getCupertinoTheme("theme", context, Brightness.light)
411414
: control.getString("dark_theme") != null
412415
? control.getCupertinoTheme("dark_theme", context, Brightness.dark)
413416
: control.getCupertinoTheme("theme", context, Brightness.dark);
@@ -466,10 +469,7 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
466469
);
467470

468471
if (control.getBool("enable_screenshots") == true) {
469-
app = RepaintBoundary(
470-
key: _rootKey,
471-
child: app,
472-
);
472+
app = RepaintBoundary(key: _rootKey, child: app);
473473
}
474474

475475
return PageContext(

packages/flet/lib/src/transport/flet_msgpack_encoder.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import 'dart:typed_data';
44
import 'package:flutter/material.dart';
55
import 'package:msgpack_dart/msgpack_dart.dart';
66

7+
import 'js_interop.dart' show JSAny;
8+
79
class FletMsgpackEncoder extends ExtEncoder {
810
final codec = const Utf8Codec();
911

@@ -15,7 +17,11 @@ class FletMsgpackEncoder extends ExtEncoder {
1517
return 2;
1618
} else if (object is Duration) {
1719
return 3;
20+
} else if (object is JSAny) {
21+
return 4;
1822
}
23+
debugPrint(
24+
"FletMsgpackEncoder: unknown type: ${object.runtimeType}: $object");
1925
return 0;
2026
}
2127

@@ -27,6 +33,8 @@ class FletMsgpackEncoder extends ExtEncoder {
2733
return codec.encode("${object.hour}:${object.minute}");
2834
} else if (object is Duration) {
2935
return codec.encode(object.inMicroseconds.toString());
36+
} else if (object is JSAny) {
37+
return codec.encode(object.toString());
3038
}
3139
return Uint8List(0);
3240
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export 'js_interop_stub.dart'
2+
if (dart.library.js_interop) 'dart:js_interop';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// Placeholder type used on non-web targets where `dart:js_interop` is absent.
2+
class JSAny {}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import 'package:device_info_plus/device_info_plus.dart';
2+
3+
import 'platform.dart';
4+
5+
/// Returns device information as a Map.
6+
Future<Map<String, dynamic>> getDeviceInfo() async {
7+
BaseDeviceInfo deviceInfo = await DeviceInfoPlugin().deviceInfo;
8+
return deviceInfo.asMap();
9+
}
10+
11+
extension DeviceInfoExtension on BaseDeviceInfo {
12+
Map<String, dynamic> asMap() {
13+
var deviceInfo = this;
14+
15+
if (isWebPlatform()) {
16+
deviceInfo = (deviceInfo as WebBrowserInfo);
17+
return {
18+
"browser_name": deviceInfo.browserName.name,
19+
"app_code_name": deviceInfo.appCodeName,
20+
"app_name": deviceInfo.appName,
21+
"app_version": deviceInfo.appVersion,
22+
"device_memory": deviceInfo.deviceMemory,
23+
"language": deviceInfo.language,
24+
"languages": deviceInfo.languages,
25+
"platform": deviceInfo.platform,
26+
"product": deviceInfo.product,
27+
"product_sub": deviceInfo.productSub,
28+
"user_agent": deviceInfo.userAgent,
29+
"vendor": deviceInfo.vendor,
30+
"vendor_sub": deviceInfo.vendorSub,
31+
"max_touch_points": deviceInfo.maxTouchPoints,
32+
"hardware_concurrency": deviceInfo.hardwareConcurrency,
33+
};
34+
} else {
35+
if (isAndroidMobile()) {
36+
deviceInfo = (deviceInfo as AndroidDeviceInfo);
37+
return {
38+
"available_ram_size": deviceInfo.availableRamSize,
39+
"board": deviceInfo.board,
40+
"bootloader": deviceInfo.bootloader,
41+
"brand": deviceInfo.brand,
42+
"device": deviceInfo.device,
43+
"display": deviceInfo.display,
44+
"fingerprint": deviceInfo.fingerprint,
45+
"free_disk_size": deviceInfo.freeDiskSize,
46+
"hardware": deviceInfo.hardware,
47+
"host": deviceInfo.host,
48+
"id": deviceInfo.id,
49+
"is_low_ram_device": deviceInfo.isLowRamDevice,
50+
"is_physical_device": deviceInfo.isPhysicalDevice,
51+
"manufacturer": deviceInfo.manufacturer,
52+
"model": deviceInfo.model,
53+
"name": deviceInfo.name,
54+
"physical_ram_size": deviceInfo.physicalRamSize,
55+
"product": deviceInfo.product,
56+
"supported_32_bit_abis": deviceInfo.supported32BitAbis,
57+
"supported_64_bit_abis": deviceInfo.supported64BitAbis,
58+
"supported_abis": deviceInfo.supportedAbis,
59+
"system_features": deviceInfo.systemFeatures,
60+
"tags": deviceInfo.tags,
61+
"total_disk_size": deviceInfo.totalDiskSize,
62+
"type": deviceInfo.type,
63+
"version": {
64+
'base_os': deviceInfo.version.baseOS,
65+
'sdk': deviceInfo.version.sdkInt,
66+
'release': deviceInfo.version.release,
67+
'code_name': deviceInfo.version.codename,
68+
'incremental': deviceInfo.version.incremental,
69+
'preview_sdk': deviceInfo.version.previewSdkInt,
70+
'security_patch': deviceInfo.version.securityPatch,
71+
},
72+
};
73+
} else if (isIOSMobile()) {
74+
deviceInfo = (deviceInfo as IosDeviceInfo);
75+
return {
76+
"available_ram_size": deviceInfo.availableRamSize,
77+
"free_disk_size": deviceInfo.freeDiskSize,
78+
"is_ios_app_on_mac": deviceInfo.isiOSAppOnMac,
79+
"is_physical_device": deviceInfo.isPhysicalDevice,
80+
"localized_model": deviceInfo.localizedModel,
81+
"model": deviceInfo.model,
82+
"model_name": deviceInfo.modelName,
83+
"name": deviceInfo.name,
84+
"physical_ram_size": deviceInfo.physicalRamSize,
85+
"system_name": deviceInfo.systemName,
86+
"system_version": deviceInfo.systemVersion,
87+
"total_disk_size": deviceInfo.totalDiskSize,
88+
"utsname": {
89+
"machine": deviceInfo.utsname.machine,
90+
"node_name": deviceInfo.utsname.nodename,
91+
"release": deviceInfo.utsname.release,
92+
"sys_name": deviceInfo.utsname.sysname,
93+
"version": deviceInfo.utsname.version,
94+
},
95+
"identifier_for_vendor": deviceInfo.identifierForVendor,
96+
};
97+
} else if (isLinuxDesktop()) {
98+
deviceInfo = (deviceInfo as LinuxDeviceInfo);
99+
return {
100+
"name": deviceInfo.name,
101+
"id": deviceInfo.id,
102+
"pretty_name": deviceInfo.prettyName,
103+
"version": deviceInfo.version,
104+
"id_like": deviceInfo.idLike,
105+
"version_code_name": deviceInfo.versionCodename,
106+
"version_id": deviceInfo.versionId,
107+
"build_id": deviceInfo.buildId,
108+
"variant": deviceInfo.variant,
109+
"variant_id": deviceInfo.variantId,
110+
"machine_id": deviceInfo.machineId,
111+
};
112+
} else if (isMacOSDesktop()) {
113+
deviceInfo = (deviceInfo as MacOsDeviceInfo);
114+
return {
115+
"active_cpus": deviceInfo.activeCPUs,
116+
"arch": deviceInfo.arch,
117+
"computer_name": deviceInfo.computerName,
118+
"cpu_frequency": deviceInfo.cpuFrequency,
119+
"host_name": deviceInfo.hostName,
120+
"kernel_version": deviceInfo.kernelVersion,
121+
"major_version": deviceInfo.majorVersion,
122+
"memory_size": deviceInfo.memorySize,
123+
"minor_version": deviceInfo.minorVersion,
124+
"model": deviceInfo.model,
125+
"model_name": deviceInfo.modelName,
126+
"os_release": deviceInfo.osRelease,
127+
"patch_version": deviceInfo.patchVersion,
128+
"system_guid": deviceInfo.systemGUID,
129+
};
130+
} else if (isWindowsDesktop()) {
131+
deviceInfo = (deviceInfo as WindowsDeviceInfo);
132+
return {
133+
"computer_name": deviceInfo.computerName,
134+
"number_of_cores": deviceInfo.numberOfCores,
135+
"system_memory": deviceInfo.systemMemoryInMegabytes,
136+
"user_name": deviceInfo.userName,
137+
"major_version": deviceInfo.majorVersion,
138+
"minor_version": deviceInfo.minorVersion,
139+
"build_number": deviceInfo.buildNumber,
140+
"platform_id": deviceInfo.platformId,
141+
"csd_version": deviceInfo.csdVersion,
142+
"service_pack_major": deviceInfo.servicePackMajor,
143+
"service_pack_minor": deviceInfo.servicePackMinor,
144+
"suit_mask": deviceInfo.suitMask,
145+
"product_type": deviceInfo.productType,
146+
"reserved": deviceInfo.reserved,
147+
"build_lab": deviceInfo.buildLab,
148+
"build_lab_ex": deviceInfo.buildLabEx,
149+
// "digital_product_id": deviceInfo.digitalProductId,
150+
"display_version": deviceInfo.displayVersion,
151+
"edition_id": deviceInfo.editionId,
152+
"install_date": deviceInfo.installDate,
153+
"product_id": deviceInfo.productId,
154+
"product_name": deviceInfo.productName,
155+
"registered_owner": deviceInfo.registeredOwner,
156+
"release_id": deviceInfo.releaseId,
157+
"device_id": deviceInfo.deviceId,
158+
};
159+
}
160+
return {};
161+
}
162+
}
163+
}

0 commit comments

Comments
 (0)