Partial web app support

This commit is contained in:
Igor Kulikov
2021-08-18 21:07:19 +03:00
parent 287e808fa8
commit b6361feca9
43 changed files with 169 additions and 107 deletions

View File

@@ -14,7 +14,7 @@ import 'package:thingsboard_client/thingsboard_client.dart';
import 'login_page_background.dart'; import 'login_page_background.dart';
class LoginPage extends TbPageWidget<LoginPage, _LoginPageState> { class LoginPage extends TbPageWidget {
LoginPage(TbContext tbContext) : super(tbContext); LoginPage(TbContext tbContext) : super(tbContext);
@@ -23,7 +23,7 @@ class LoginPage extends TbPageWidget<LoginPage, _LoginPageState> {
} }
class _LoginPageState extends TbPageState<LoginPage, _LoginPageState> { class _LoginPageState extends TbPageState<LoginPage> {
final ButtonStyle _oauth2ButtonWithTextStyle = final ButtonStyle _oauth2ButtonWithTextStyle =
OutlinedButton.styleFrom(padding: EdgeInsets.all(16), OutlinedButton.styleFrom(padding: EdgeInsets.all(16),

View File

@@ -7,7 +7,7 @@ import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'package:thingsboard_app/widgets/tb_progress_indicator.dart'; import 'package:thingsboard_app/widgets/tb_progress_indicator.dart';
class ResetPasswordRequestPage extends TbPageWidget<ResetPasswordRequestPage, _ResetPasswordRequestPageState> { class ResetPasswordRequestPage extends TbPageWidget {
ResetPasswordRequestPage(TbContext tbContext) : super(tbContext); ResetPasswordRequestPage(TbContext tbContext) : super(tbContext);
@@ -16,7 +16,7 @@ class ResetPasswordRequestPage extends TbPageWidget<ResetPasswordRequestPage, _R
} }
class _ResetPasswordRequestPageState extends TbPageState<ResetPasswordRequestPage, _ResetPasswordRequestPageState> { class _ResetPasswordRequestPageState extends TbPageState<ResetPasswordRequestPage> {
final _isLoadingNotifier = ValueNotifier<bool>(false); final _isLoadingNotifier = ValueNotifier<bool>(false);

View File

@@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'package:universal_platform/universal_platform.dart';
import 'package:device_info/device_info.dart'; import 'package:device_info/device_info.dart';
import 'package:fluro/fluro.dart'; import 'package:fluro/fluro.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@@ -13,7 +12,7 @@ import 'package:thingsboard_app/core/auth/oauth2/tb_oauth2_client.dart';
import 'package:thingsboard_app/modules/main/main_page.dart'; import 'package:thingsboard_app/modules/main/main_page.dart';
import 'package:thingsboard_app/utils/services/widget_action_handler.dart'; import 'package:thingsboard_app/utils/services/widget_action_handler.dart';
import 'package:thingsboard_client/thingsboard_client.dart'; import 'package:thingsboard_client/thingsboard_client.dart';
import 'package:thingsboard_app/utils/services/tb_secure_storage.dart'; import 'package:thingsboard_app/utils/services/tb_app_storage.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart'; import 'package:thingsboard_app/core/context/tb_context_widget.dart';
enum NotificationType { enum NotificationType {
@@ -145,8 +144,9 @@ class TbContext {
return true; return true;
}()); }());
_initialized = true; _initialized = true;
var storage = createAppStorage();
tbClient = ThingsboardClient(ThingsboardAppConstants.thingsBoardApiEndpoint, tbClient = ThingsboardClient(ThingsboardAppConstants.thingsBoardApiEndpoint,
storage: TbSecureStorage(), storage: storage,
onUserLoaded: onUserLoaded, onUserLoaded: onUserLoaded,
onError: onError, onError: onError,
onLoadStarted: onLoadStarted, onLoadStarted: onLoadStarted,
@@ -156,15 +156,21 @@ class TbContext {
oauth2Client = TbOAuth2Client(tbContext: this, appSecretProvider: AppSecretProvider.local()); oauth2Client = TbOAuth2Client(tbContext: this, appSecretProvider: AppSecretProvider.local());
try { try {
if (Platform.isAndroid) { if (UniversalPlatform.isAndroid) {
_androidInfo = await deviceInfoPlugin.androidInfo; _androidInfo = await deviceInfoPlugin.androidInfo;
_oauth2PlatformType = PlatformType.ANDROID; _oauth2PlatformType = PlatformType.ANDROID;
} else if (Platform.isIOS) { } else if (UniversalPlatform.isIOS) {
_iosInfo = await deviceInfoPlugin.iosInfo; _iosInfo = await deviceInfoPlugin.iosInfo;
_oauth2PlatformType = PlatformType.IOS; _oauth2PlatformType = PlatformType.IOS;
} else {
_oauth2PlatformType = PlatformType.WEB;
}
if (UniversalPlatform.isAndroid || UniversalPlatform.isIOS) {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
packageName = packageInfo.packageName;
} else {
packageName = 'web.app';
} }
PackageInfo packageInfo = await PackageInfo.fromPlatform();
packageName = packageInfo.packageName;
await tbClient.init(); await tbClient.init();
} catch (e, s) { } catch (e, s) {
log.error('Failed to init tbContext: $e', e, s); log.error('Failed to init tbContext: $e', e, s);
@@ -337,9 +343,9 @@ class TbContext {
} }
bool isPhysicalDevice() { bool isPhysicalDevice() {
if (Platform.isAndroid) { if (UniversalPlatform.isAndroid) {
return _androidInfo!.isPhysicalDevice; return _androidInfo!.isPhysicalDevice;
} else if (Platform.isIOS) { } else if (UniversalPlatform.isIOS) {
return _iosInfo!.isPhysicalDevice; return _iosInfo!.isPhysicalDevice;
} else { } else {
return false; return false;
@@ -348,9 +354,9 @@ class TbContext {
String userAgent() { String userAgent() {
String userAgent = 'Mozilla/5.0'; String userAgent = 'Mozilla/5.0';
if (Platform.isAndroid) { if (UniversalPlatform.isAndroid) {
userAgent += ' (Linux; Android ${_androidInfo!.version.release}; ${_androidInfo!.model})'; userAgent += ' (Linux; Android ${_androidInfo!.version.release}; ${_androidInfo!.model})';
} else if (Platform.isIOS) { } else if (UniversalPlatform.isIOS) {
userAgent += ' (${_iosInfo!.model})'; userAgent += ' (${_iosInfo!.model})';
} }
userAgent += ' AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36'; userAgent += ' AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36';

View File

@@ -12,13 +12,13 @@ abstract class TbContextStatelessWidget extends StatelessWidget with HasTbContex
} }
} }
abstract class TbContextWidget<W extends TbContextWidget<W,S>, S extends TbContextState<W,S>> extends StatefulWidget with HasTbContext { abstract class TbContextWidget extends StatefulWidget with HasTbContext {
TbContextWidget(TbContext tbContext, {Key? key}) : super(key: key) { TbContextWidget(TbContext tbContext, {Key? key}) : super(key: key) {
setTbContext(tbContext); setTbContext(tbContext);
} }
} }
abstract class TbContextState<W extends TbContextWidget<W,S>, S extends TbContextState<W,S>> extends State<W> with HasTbContext { abstract class TbContextState<T extends TbContextWidget> extends State<T> with HasTbContext {
final bool handleLoading; final bool handleLoading;
@@ -47,11 +47,11 @@ mixin TbMainState {
} }
abstract class TbPageWidget<W extends TbPageWidget<W,S>, S extends TbPageState<W,S>> extends TbContextWidget<W,S> { abstract class TbPageWidget extends TbContextWidget {
TbPageWidget(TbContext tbContext, {Key? key}) : super(tbContext, key: key); TbPageWidget(TbContext tbContext, {Key? key}) : super(tbContext, key: key);
} }
abstract class TbPageState<W extends TbPageWidget<W,S>, S extends TbPageState<W,S>> extends TbContextState<W,S> with RouteAware { abstract class TbPageState<W extends TbPageWidget> extends TbContextState<W> with RouteAware {
TbPageState({bool handleUserLoaded = false}): super(handleLoading: true); TbPageState({bool handleUserLoaded = false}): super(handleLoading: true);
@override @override
@@ -79,7 +79,7 @@ abstract class TbPageState<W extends TbPageWidget<W,S>, S extends TbPageState<W,
} }
class TextContextWidget extends TbContextWidget<TextContextWidget, _TextContextWidgetState> { class TextContextWidget extends TbContextWidget {
final String text; final String text;
@@ -90,7 +90,7 @@ class TextContextWidget extends TbContextWidget<TextContextWidget, _TextContextW
} }
class _TextContextWidgetState extends TbContextState<TextContextWidget, _TextContextWidgetState> { class _TextContextWidgetState extends TbContextState<TextContextWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@@ -193,7 +193,7 @@ class TimePageLinkController extends PageKeyController<TimePageLink> {
} }
abstract class BaseEntitiesWidget<T, P> extends TbContextWidget<BaseEntitiesWidget<T, P>, BaseEntitiesState<T, P>> with EntitiesBase<T, P> { abstract class BaseEntitiesWidget<T, P> extends TbContextWidget with EntitiesBase<T, P> {
final bool searchMode; final bool searchMode;
final PageKeyController<P> pageKeyController; final PageKeyController<P> pageKeyController;
@@ -211,7 +211,7 @@ abstract class BaseEntitiesWidget<T, P> extends TbContextWidget<BaseEntitiesWidg
} }
abstract class BaseEntitiesState<T, P> extends TbContextState<BaseEntitiesWidget<T, P>, BaseEntitiesState<T, P>> { abstract class BaseEntitiesState<T, P> extends TbContextState<BaseEntitiesWidget<T, P>> {
late final PagingController<P, T> pagingController; late final PagingController<P, T> pagingController;
Completer<void>? _refreshCompleter; Completer<void>? _refreshCompleter;

View File

@@ -41,7 +41,7 @@ abstract class EntitiesListPageLinkWidget<T> extends EntitiesListWidget<T, PageL
} }
abstract class EntitiesListWidget<T, P> extends TbContextWidget<EntitiesListWidget<T,P>, _EntitiesListWidgetState<T,P>> with EntitiesBase<T,P> { abstract class EntitiesListWidget<T, P> extends TbContextWidget with EntitiesBase<T,P> {
final EntitiesListWidgetController? _controller; final EntitiesListWidgetController? _controller;
@@ -58,7 +58,7 @@ abstract class EntitiesListWidget<T, P> extends TbContextWidget<EntitiesListWidg
} }
class _EntitiesListWidgetState<T,P> extends TbContextState<EntitiesListWidget<T,P>, _EntitiesListWidgetState<T,P>> { class _EntitiesListWidgetState<T,P> extends TbContextState<EntitiesListWidget<T,P>> {
final EntitiesListWidgetController? _controller; final EntitiesListWidgetController? _controller;

View File

@@ -7,7 +7,7 @@ import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'package:thingsboard_app/widgets/tb_progress_indicator.dart'; import 'package:thingsboard_app/widgets/tb_progress_indicator.dart';
import 'package:thingsboard_client/thingsboard_client.dart'; import 'package:thingsboard_client/thingsboard_client.dart';
abstract class EntityDetailsPage<T extends BaseData> extends TbPageWidget<EntityDetailsPage<T>, _EntityDetailsPageState<T>> { abstract class EntityDetailsPage<T extends BaseData> extends TbPageWidget {
final labelTextStyle = TextStyle( final labelTextStyle = TextStyle(
color: Color(0xFF757575), color: Color(0xFF757575),
@@ -56,7 +56,7 @@ abstract class EntityDetailsPage<T extends BaseData> extends TbPageWidget<Entity
} }
class _EntityDetailsPageState<T extends BaseData> extends TbPageState<EntityDetailsPage<T>, _EntityDetailsPageState<T>> { class _EntityDetailsPageState<T extends BaseData> extends TbPageState<EntityDetailsPage<T>> {
late Future<T?> entityFuture; late Future<T?> entityFuture;
late ValueNotifier<String> titleValue; late ValueNotifier<String> titleValue;

View File

@@ -4,7 +4,7 @@ import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart'; import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/widgets/tb_progress_indicator.dart'; import 'package:thingsboard_app/widgets/tb_progress_indicator.dart';
class ThingsboardInitApp extends TbPageWidget<ThingsboardInitApp, _ThingsboardInitAppState> { class ThingsboardInitApp extends TbPageWidget {
ThingsboardInitApp(TbContext tbContext, {Key? key}) : super(tbContext, key: key); ThingsboardInitApp(TbContext tbContext, {Key? key}) : super(tbContext, key: key);
@@ -13,7 +13,7 @@ class ThingsboardInitApp extends TbPageWidget<ThingsboardInitApp, _ThingsboardIn
} }
class _ThingsboardInitAppState extends TbPageState<ThingsboardInitApp, _ThingsboardInitAppState> { class _ThingsboardInitAppState extends TbPageState<ThingsboardInitApp> {
@override @override
void initState() { void initState() {

View File

@@ -1,4 +1,4 @@
import 'dart:io'; import 'package:universal_platform/universal_platform.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -19,7 +19,7 @@ void main() async {
// await FlutterDownloader.initialize(); // await FlutterDownloader.initialize();
// await Permission.storage.request(); // await Permission.storage.request();
if (Platform.isAndroid) { if (UniversalPlatform.isAndroid) {
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true); await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
} }

View File

@@ -86,7 +86,7 @@ class AlarmQueryController extends PageKeyController<AlarmQuery> {
} }
class AlarmCard extends TbContextWidget<AlarmCard, _AlarmCardState> { class AlarmCard extends TbContextWidget {
final AlarmInfo alarm; final AlarmInfo alarm;
@@ -97,7 +97,7 @@ class AlarmCard extends TbContextWidget<AlarmCard, _AlarmCardState> {
} }
class _AlarmCardState extends TbContextState<AlarmCard, _AlarmCardState> { class _AlarmCardState extends TbContextState<AlarmCard> {
bool loading = false; bool loading = false;
AlarmInfo alarm; AlarmInfo alarm;

View File

@@ -6,7 +6,7 @@ import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'alarms_list.dart'; import 'alarms_list.dart';
class AlarmsPage extends TbContextWidget<AlarmsPage, _AlarmsPageState> { class AlarmsPage extends TbContextWidget {
final bool searchMode; final bool searchMode;
@@ -17,7 +17,7 @@ class AlarmsPage extends TbContextWidget<AlarmsPage, _AlarmsPageState> {
} }
class _AlarmsPageState extends TbContextState<AlarmsPage, _AlarmsPageState> with AutomaticKeepAliveClientMixin<AlarmsPage> { class _AlarmsPageState extends TbContextState<AlarmsPage> with AutomaticKeepAliveClientMixin<AlarmsPage> {
final AlarmQueryController _alarmQueryController = AlarmQueryController(); final AlarmQueryController _alarmQueryController = AlarmQueryController();

View File

@@ -6,7 +6,7 @@ import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'assets_list.dart'; import 'assets_list.dart';
class AssetsPage extends TbPageWidget<AssetsPage, _AssetsPageState> { class AssetsPage extends TbPageWidget {
final bool searchMode; final bool searchMode;
@@ -17,7 +17,7 @@ class AssetsPage extends TbPageWidget<AssetsPage, _AssetsPageState> {
} }
class _AssetsPageState extends TbPageState<AssetsPage, _AssetsPageState> { class _AssetsPageState extends TbPageState<AssetsPage> {
final PageLinkController _pageLinkController = PageLinkController(); final PageLinkController _pageLinkController = PageLinkController();

View File

@@ -8,7 +8,7 @@ import 'package:thingsboard_app/modules/audit_log/audit_logs_base.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'package:thingsboard_client/thingsboard_client.dart'; import 'package:thingsboard_client/thingsboard_client.dart';
class AuditLogDetailsPage extends TbContextWidget<AuditLogDetailsPage, _AuditLogDetailsPageState> { class AuditLogDetailsPage extends TbContextWidget {
final AuditLog auditLog; final AuditLog auditLog;
@@ -19,7 +19,7 @@ class AuditLogDetailsPage extends TbContextWidget<AuditLogDetailsPage, _AuditLog
} }
class _AuditLogDetailsPageState extends TbContextState<AuditLogDetailsPage, _AuditLogDetailsPageState> { class _AuditLogDetailsPageState extends TbContextState<AuditLogDetailsPage> {
final labelTextStyle = TextStyle( final labelTextStyle = TextStyle(
color: Color(0xFF757575), color: Color(0xFF757575),

View File

@@ -72,7 +72,7 @@ mixin AuditLogsBase on EntitiesBase<AuditLog, TimePageLink> {
} }
} }
class AuditLogCard extends TbContextWidget<AuditLogCard, _AuditLogCardState> { class AuditLogCard extends TbContextWidget {
final AuditLog auditLog; final AuditLog auditLog;
@@ -83,7 +83,7 @@ class AuditLogCard extends TbContextWidget<AuditLogCard, _AuditLogCardState> {
} }
class _AuditLogCardState extends TbContextState<AuditLogCard, _AuditLogCardState> { class _AuditLogCardState extends TbContextState<AuditLogCard> {
final entityDateFormat = DateFormat('yyyy-MM-dd'); final entityDateFormat = DateFormat('yyyy-MM-dd');

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'package:thingsboard_app/modules/audit_log/audit_logs_list.dart'; import 'package:thingsboard_app/modules/audit_log/audit_logs_list.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
class AuditLogsPage extends TbPageWidget<AuditLogsPage, _AuditLogsPageState> { class AuditLogsPage extends TbPageWidget {
final bool searchMode; final bool searchMode;
@@ -16,7 +16,7 @@ class AuditLogsPage extends TbPageWidget<AuditLogsPage, _AuditLogsPageState> {
} }
class _AuditLogsPageState extends TbPageState<AuditLogsPage, _AuditLogsPageState> { class _AuditLogsPageState extends TbPageState<AuditLogsPage> {
final TimePageLinkController _timePageLinkController = TimePageLinkController(); final TimePageLinkController _timePageLinkController = TimePageLinkController();

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'package:thingsboard_app/modules/customer/customers_list.dart'; import 'package:thingsboard_app/modules/customer/customers_list.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
class CustomersPage extends TbPageWidget<CustomersPage, _CustomersPageState> { class CustomersPage extends TbPageWidget {
final bool searchMode; final bool searchMode;
@@ -16,7 +16,7 @@ class CustomersPage extends TbPageWidget<CustomersPage, _CustomersPageState> {
} }
class _CustomersPageState extends TbPageState<CustomersPage, _CustomersPageState> { class _CustomersPageState extends TbPageState<CustomersPage> {
final PageLinkController _pageLinkController = PageLinkController(); final PageLinkController _pageLinkController = PageLinkController();

View File

@@ -10,6 +10,7 @@ import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart'; import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/widgets/tb_progress_indicator.dart'; import 'package:thingsboard_app/widgets/tb_progress_indicator.dart';
import 'package:thingsboard_app/widgets/two_value_listenable_builder.dart'; import 'package:thingsboard_app/widgets/two_value_listenable_builder.dart';
import 'package:universal_platform/universal_platform.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class DashboardController { class DashboardController {
@@ -65,7 +66,7 @@ typedef DashboardTitleCallback = void Function(String title);
typedef DashboardControllerCallback = void Function(DashboardController controller); typedef DashboardControllerCallback = void Function(DashboardController controller);
class Dashboard extends TbContextWidget<Dashboard, _DashboardState> { class Dashboard extends TbContextWidget {
final bool? _home; final bool? _home;
final bool _activeByDefault; final bool _activeByDefault;
@@ -84,7 +85,7 @@ class Dashboard extends TbContextWidget<Dashboard, _DashboardState> {
} }
class _DashboardState extends TbContextState<Dashboard, _DashboardState> { class _DashboardState extends TbContextState<Dashboard> {
final Completer<InAppWebViewController> _controller = Completer<InAppWebViewController>(); final Completer<InAppWebViewController> _controller = Completer<InAppWebViewController>();
@@ -145,21 +146,27 @@ class _DashboardState extends TbContextState<Dashboard, _DashboardState> {
'refreshToken': tbClient.getRefreshToken()! 'refreshToken': tbClient.getRefreshToken()!
} }
}; };
var controller = await _controller.future; if (!UniversalPlatform.isWeb) {
await controller.postWebMessage(message: WebMessage(data: jsonEncode(windowMessage)), targetOrigin: Uri.parse('*')); var controller = await _controller.future;
await controller.postWebMessage(
message: WebMessage(data: jsonEncode(windowMessage)),
targetOrigin: Uri.parse('*'));
}
} }
} }
} }
Future<bool> _goBack() async { Future<bool> _goBack() async {
if (_dashboardController.rightLayoutOpened.value) { if (!UniversalPlatform.isWeb) {
await _toggleRightLayout(); if (_dashboardController.rightLayoutOpened.value) {
return false; await _toggleRightLayout();
} return false;
var controller = await _controller.future; }
if (await controller.canGoBack()) { var controller = await _controller.future;
await controller.goBack(); if (await controller.canGoBack()) {
return false; await controller.goBack();
return false;
}
} }
return true; return true;
} }
@@ -188,7 +195,10 @@ class _DashboardState extends TbContextState<Dashboard, _DashboardState> {
Future<void> _openDashboard(String dashboardId, {String? state, bool? hideToolbar, bool fullscreen = false}) async { Future<void> _openDashboard(String dashboardId, {String? state, bool? hideToolbar, bool fullscreen = false}) async {
_fullscreen = fullscreen; _fullscreen = fullscreen;
dashboardLoading.value = true; dashboardLoading.value = true;
var controller = await _controller.future; InAppWebViewController? controller;
if (!UniversalPlatform.isWeb) {
controller = await _controller.future;
}
var windowMessage = <String, dynamic>{ var windowMessage = <String, dynamic>{
'type': 'openDashboardMessage', 'type': 'openDashboardMessage',
'data': <String, dynamic>{ 'data': <String, dynamic>{
@@ -205,7 +215,10 @@ class _DashboardState extends TbContextState<Dashboard, _DashboardState> {
windowMessage['data']['hideToolbar'] = true; windowMessage['data']['hideToolbar'] = true;
} }
var webMessage = WebMessage(data: jsonEncode(windowMessage)); var webMessage = WebMessage(data: jsonEncode(windowMessage));
await controller.postWebMessage(message: webMessage, targetOrigin: Uri.parse('*')); if (!UniversalPlatform.isWeb) {
await controller!.postWebMessage(
message: webMessage, targetOrigin: Uri.parse('*'));
}
} }
Future<void> _toggleRightLayout() async { Future<void> _toggleRightLayout() async {
@@ -239,6 +252,7 @@ class _DashboardState extends TbContextState<Dashboard, _DashboardState> {
} else { } else {
return Stack( return Stack(
children: [ children: [
UniversalPlatform.isWeb ? Center(child: Text('Not implemented!')) :
InAppWebView( InAppWebView(
key: webViewKey, key: webViewKey,
initialUrlRequest: URLRequest(url: _initialUrl), initialUrlRequest: URLRequest(url: _initialUrl),
@@ -348,7 +362,8 @@ class _DashboardState extends TbContextState<Dashboard, _DashboardState> {
action: PermissionRequestResponseAction.GRANT); action: PermissionRequestResponseAction.GRANT);
}, },
), ),
TwoValueListenableBuilder( if (!UniversalPlatform.isWeb)
TwoValueListenableBuilder(
firstValueListenable: dashboardLoading, firstValueListenable: dashboardLoading,
secondValueListenable: dashboardActive, secondValueListenable: dashboardActive,
builder: (BuildContext context, bool loading, bool active, child) { builder: (BuildContext context, bool loading, bool active, child) {

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/modules/dashboard/dashboard.dart'; import 'package:thingsboard_app/modules/dashboard/dashboard.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
class DashboardPage extends TbPageWidget<DashboardPage, _DashboardPageState> { class DashboardPage extends TbPageWidget {
final String? _dashboardTitle; final String? _dashboardTitle;
final String? _dashboardId; final String? _dashboardId;
@@ -24,7 +24,7 @@ class DashboardPage extends TbPageWidget<DashboardPage, _DashboardPageState> {
} }
class _DashboardPageState extends TbPageState<DashboardPage, _DashboardPageState> { class _DashboardPageState extends TbPageState<DashboardPage> {
late ValueNotifier<String> dashboardTitleValue; late ValueNotifier<String> dashboardTitleValue;

View File

@@ -127,7 +127,7 @@ mixin DashboardsBase on EntitiesBase<DashboardInfo, PageLink> {
} }
class DashboardGridCard extends TbContextWidget<DashboardGridCard, _DashboardGridCardState> { class DashboardGridCard extends TbContextWidget {
final DashboardInfo dashboard; final DashboardInfo dashboard;
@@ -138,7 +138,7 @@ class DashboardGridCard extends TbContextWidget<DashboardGridCard, _DashboardGri
} }
class _DashboardGridCardState extends TbContextState<DashboardGridCard, _DashboardGridCardState> { class _DashboardGridCardState extends TbContextState<DashboardGridCard> {
_DashboardGridCardState(): super(); _DashboardGridCardState(): super();

View File

@@ -7,7 +7,7 @@ import 'package:thingsboard_client/thingsboard_client.dart';
import 'dashboards_base.dart'; import 'dashboards_base.dart';
class DashboardsGridWidget extends TbContextWidget<DashboardsGridWidget, _DashboardsGridWidgetState> { class DashboardsGridWidget extends TbContextWidget {
DashboardsGridWidget(TbContext tbContext) : super(tbContext); DashboardsGridWidget(TbContext tbContext) : super(tbContext);
@@ -16,7 +16,7 @@ class DashboardsGridWidget extends TbContextWidget<DashboardsGridWidget, _Dashbo
} }
class _DashboardsGridWidgetState extends TbContextState<DashboardsGridWidget, _DashboardsGridWidgetState> { class _DashboardsGridWidgetState extends TbContextState<DashboardsGridWidget> {
final PageLinkController _pageLinkController = PageLinkController(); final PageLinkController _pageLinkController = PageLinkController();

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'dashboards_grid.dart'; import 'dashboards_grid.dart';
class DashboardsPage extends TbPageWidget<DashboardsPage, _DashboardsPageState> { class DashboardsPage extends TbPageWidget {
DashboardsPage(TbContext tbContext) : super(tbContext); DashboardsPage(TbContext tbContext) : super(tbContext);
@@ -14,7 +14,7 @@ class DashboardsPage extends TbPageWidget<DashboardsPage, _DashboardsPageState>
} }
class _DashboardsPageState extends TbPageState<DashboardsPage, _DashboardsPageState> { class _DashboardsPageState extends TbPageState<DashboardsPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/modules/dashboard/dashboard.dart'; import 'package:thingsboard_app/modules/dashboard/dashboard.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
class FullscreenDashboardPage extends TbPageWidget<FullscreenDashboardPage, _FullscreenDashboardPageState> { class FullscreenDashboardPage extends TbPageWidget {
final String fullscreenDashboardId; final String fullscreenDashboardId;
final String? _dashboardTitle; final String? _dashboardTitle;
@@ -19,7 +19,7 @@ class FullscreenDashboardPage extends TbPageWidget<FullscreenDashboardPage, _Ful
} }
class _FullscreenDashboardPageState extends TbPageState<FullscreenDashboardPage, _FullscreenDashboardPageState> { class _FullscreenDashboardPageState extends TbPageState<FullscreenDashboardPage> {
late ValueNotifier<String> dashboardTitleValue; late ValueNotifier<String> dashboardTitleValue;
final ValueNotifier<bool> showBackValue = ValueNotifier(false); final ValueNotifier<bool> showBackValue = ValueNotifier(false);

View File

@@ -43,7 +43,7 @@ class MainDashboardPageController {
} }
class MainDashboardPage extends TbContextWidget<MainDashboardPage, _MainDashboardPageState> { class MainDashboardPage extends TbContextWidget {
final String? _dashboardTitle; final String? _dashboardTitle;
final MainDashboardPageController? _controller; final MainDashboardPageController? _controller;
@@ -60,7 +60,7 @@ class MainDashboardPage extends TbContextWidget<MainDashboardPage, _MainDashboar
} }
class _MainDashboardPageState extends TbContextState<MainDashboardPage, _MainDashboardPageState> with TickerProviderStateMixin { class _MainDashboardPageState extends TbContextState<MainDashboardPage> with TickerProviderStateMixin {
late ValueNotifier<String> dashboardTitleValue; late ValueNotifier<String> dashboardTitleValue;
final ValueNotifier<bool> hasRightLayout = ValueNotifier(false); final ValueNotifier<bool> hasRightLayout = ValueNotifier(false);

View File

@@ -63,7 +63,7 @@ class RefreshDeviceCounts {
Future<void> Function()? onRefresh; Future<void> Function()? onRefresh;
} }
class AllDevicesCard extends TbContextWidget<AllDevicesCard, _AllDevicesCardState> { class AllDevicesCard extends TbContextWidget {
final RefreshDeviceCounts refreshDeviceCounts; final RefreshDeviceCounts refreshDeviceCounts;
@@ -74,7 +74,7 @@ class AllDevicesCard extends TbContextWidget<AllDevicesCard, _AllDevicesCardStat
} }
class _AllDevicesCardState extends TbContextState<AllDevicesCard, _AllDevicesCardState> { class _AllDevicesCardState extends TbContextState<AllDevicesCard> {
final StreamController<int?> _activeDevicesCount = StreamController.broadcast(); final StreamController<int?> _activeDevicesCount = StreamController.broadcast();
final StreamController<int?> _inactiveDevicesCount = StreamController.broadcast(); final StreamController<int?> _inactiveDevicesCount = StreamController.broadcast();
@@ -240,7 +240,7 @@ class _AllDevicesCardState extends TbContextState<AllDevicesCard, _AllDevicesCar
} }
class DeviceProfileCard extends TbContextWidget<DeviceProfileCard, _DeviceProfileCardState> { class DeviceProfileCard extends TbContextWidget {
final DeviceProfileInfo deviceProfile; final DeviceProfileInfo deviceProfile;
@@ -251,7 +251,7 @@ class DeviceProfileCard extends TbContextWidget<DeviceProfileCard, _DeviceProfil
} }
class _DeviceProfileCardState extends TbContextState<DeviceProfileCard, _DeviceProfileCardState> { class _DeviceProfileCardState extends TbContextState<DeviceProfileCard> {
late Future<int> activeDevicesCount; late Future<int> activeDevicesCount;
late Future<int> inactiveDevicesCount; late Future<int> inactiveDevicesCount;

View File

@@ -78,7 +78,7 @@ class DeviceQueryController extends PageKeyController<EntityDataQuery> {
} }
class DeviceCard extends TbContextWidget<DeviceCard, _DeviceCardState> { class DeviceCard extends TbContextWidget {
final EntityData device; final EntityData device;
final bool listWidgetCard; final bool listWidgetCard;
@@ -91,7 +91,7 @@ class DeviceCard extends TbContextWidget<DeviceCard, _DeviceCardState> {
} }
class _DeviceCardState extends TbContextState<DeviceCard, _DeviceCardState> { class _DeviceCardState extends TbContextState<DeviceCard> {
final entityDateFormat = DateFormat('yyyy-MM-dd'); final entityDateFormat = DateFormat('yyyy-MM-dd');

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/modules/device/devices_base.dart';
import 'package:thingsboard_app/modules/device/devices_list.dart'; import 'package:thingsboard_app/modules/device/devices_list.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
class DevicesListPage extends TbPageWidget<DevicesListPage, _DevicesListPageState> { class DevicesListPage extends TbPageWidget {
final String? deviceType; final String? deviceType;
final bool? active; final bool? active;
@@ -18,7 +18,7 @@ class DevicesListPage extends TbPageWidget<DevicesListPage, _DevicesListPageStat
} }
class _DevicesListPageState extends TbPageState<DevicesListPage, _DevicesListPageState> { class _DevicesListPageState extends TbPageState<DevicesListPage> {
late final DeviceQueryController _deviceQueryController; late final DeviceQueryController _deviceQueryController;

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'package:thingsboard_app/modules/device/device_profiles_grid.dart'; import 'package:thingsboard_app/modules/device/device_profiles_grid.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
class DevicesMainPage extends TbContextWidget<DevicesMainPage, _DevicesMainPageState> { class DevicesMainPage extends TbContextWidget {
DevicesMainPage(TbContext tbContext) : super(tbContext); DevicesMainPage(TbContext tbContext) : super(tbContext);
@@ -14,7 +14,7 @@ class DevicesMainPage extends TbContextWidget<DevicesMainPage, _DevicesMainPageS
} }
class _DevicesMainPageState extends TbContextState<DevicesMainPage, _DevicesMainPageState> with AutomaticKeepAliveClientMixin<DevicesMainPage> { class _DevicesMainPageState extends TbContextState<DevicesMainPage> with AutomaticKeepAliveClientMixin<DevicesMainPage> {
final PageLinkController _pageLinkController = PageLinkController(); final PageLinkController _pageLinkController = PageLinkController();

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'package:thingsboard_app/modules/device/device_profiles_grid.dart'; import 'package:thingsboard_app/modules/device/device_profiles_grid.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
class DevicesPage extends TbPageWidget<DevicesPage, _DevicesPageState> { class DevicesPage extends TbPageWidget {
DevicesPage(TbContext tbContext) : super(tbContext); DevicesPage(TbContext tbContext) : super(tbContext);
@@ -14,7 +14,7 @@ class DevicesPage extends TbPageWidget<DevicesPage, _DevicesPageState> {
} }
class _DevicesPageState extends TbPageState<DevicesPage, _DevicesPageState> { class _DevicesPageState extends TbPageState<DevicesPage> {
final PageLinkController _pageLinkController = PageLinkController(); final PageLinkController _pageLinkController = PageLinkController();

View File

@@ -10,7 +10,7 @@ import 'package:thingsboard_app/modules/tenant/tenants_widget.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'package:thingsboard_client/thingsboard_client.dart'; import 'package:thingsboard_client/thingsboard_client.dart';
class HomePage extends TbContextWidget<HomePage, _HomePageState> { class HomePage extends TbContextWidget {
HomePage(TbContext tbContext) : super(tbContext); HomePage(TbContext tbContext) : super(tbContext);
@@ -19,7 +19,7 @@ class HomePage extends TbContextWidget<HomePage, _HomePageState> {
} }
class _HomePageState extends TbContextState<HomePage, _HomePageState> with AutomaticKeepAliveClientMixin<HomePage> { class _HomePageState extends TbContextState<HomePage> with AutomaticKeepAliveClientMixin<HomePage> {
@override @override
void initState() { void initState() {
@@ -94,7 +94,7 @@ class _HomePageState extends TbContextState<HomePage, _HomePageState> with Autom
} }
class HomeDashboard extends TbContextWidget<HomeDashboard, _HomeDashboardState> { class HomeDashboard extends TbContextWidget {
final HomeDashboardInfo dashboard; final HomeDashboardInfo dashboard;
@@ -105,7 +105,7 @@ class HomeDashboard extends TbContextWidget<HomeDashboard, _HomeDashboardState>
} }
class _HomeDashboardState extends TbContextState<HomeDashboard, _HomeDashboardState> { class _HomeDashboardState extends TbContextState<HomeDashboard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@@ -85,7 +85,7 @@ class TbMainNavigationItem {
} }
} }
class MainPage extends TbPageWidget<MainPage, _MainPageState> { class MainPage extends TbPageWidget {
final String _path; final String _path;
@@ -97,7 +97,7 @@ class MainPage extends TbPageWidget<MainPage, _MainPageState> {
} }
class _MainPageState extends TbPageState<MainPage, _MainPageState> with TbMainState, TickerProviderStateMixin { class _MainPageState extends TbPageState<MainPage> with TbMainState, TickerProviderStateMixin {
late ValueNotifier<int> _currentIndexNotifier; late ValueNotifier<int> _currentIndexNotifier;
late final List<TbMainNavigationItem> _tabItems; late final List<TbMainNavigationItem> _tabItems;

View File

@@ -3,7 +3,7 @@ import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart'; import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_client/thingsboard_client.dart'; import 'package:thingsboard_client/thingsboard_client.dart';
class MorePage extends TbContextWidget<MorePage, _MorePageState> { class MorePage extends TbContextWidget {
MorePage(TbContext tbContext) : super(tbContext); MorePage(TbContext tbContext) : super(tbContext);
@@ -12,7 +12,7 @@ class MorePage extends TbContextWidget<MorePage, _MorePageState> {
} }
class _MorePageState extends TbContextState<MorePage, _MorePageState> { class _MorePageState extends TbContextState<MorePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/widgets/tb_app_bar.dart'; import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'package:thingsboard_app/widgets/tb_progress_indicator.dart'; import 'package:thingsboard_app/widgets/tb_progress_indicator.dart';
class ChangePasswordPage extends TbContextWidget<ChangePasswordPage, _ChangePasswordPageState> { class ChangePasswordPage extends TbContextWidget {
ChangePasswordPage(TbContext tbContext) : super(tbContext); ChangePasswordPage(TbContext tbContext) : super(tbContext);
@@ -14,7 +14,7 @@ class ChangePasswordPage extends TbContextWidget<ChangePasswordPage, _ChangePass
} }
class _ChangePasswordPageState extends TbContextState<ChangePasswordPage, _ChangePasswordPageState> { class _ChangePasswordPageState extends TbContextState<ChangePasswordPage> {
final _isLoadingNotifier = ValueNotifier<bool>(false); final _isLoadingNotifier = ValueNotifier<bool>(false);

View File

@@ -9,7 +9,7 @@ import 'package:thingsboard_app/core/context/tb_context_widget.dart';
import 'package:thingsboard_app/widgets/tb_progress_indicator.dart'; import 'package:thingsboard_app/widgets/tb_progress_indicator.dart';
import 'package:thingsboard_client/thingsboard_client.dart'; import 'package:thingsboard_client/thingsboard_client.dart';
class ProfilePage extends TbPageWidget<ProfilePage, _ProfilePageState> { class ProfilePage extends TbPageWidget {
final bool _fullscreen; final bool _fullscreen;
@@ -20,7 +20,7 @@ class ProfilePage extends TbPageWidget<ProfilePage, _ProfilePageState> {
} }
class _ProfilePageState extends TbPageState<ProfilePage, _ProfilePageState> { class _ProfilePageState extends TbPageState<ProfilePage> {
final _isLoadingNotifier = ValueNotifier<bool>(true); final _isLoadingNotifier = ValueNotifier<bool>(true);

View File

@@ -6,7 +6,7 @@ import 'package:thingsboard_app/widgets/tb_app_bar.dart';
import 'tenants_list.dart'; import 'tenants_list.dart';
class TenantsPage extends TbPageWidget<TenantsPage, _TenantsPageState> { class TenantsPage extends TbPageWidget {
final bool searchMode; final bool searchMode;
@@ -17,7 +17,7 @@ class TenantsPage extends TbPageWidget<TenantsPage, _TenantsPageState> {
} }
class _TenantsPageState extends TbPageState<TenantsPage, _TenantsPageState> { class _TenantsPageState extends TbPageState<TenantsPage> {
final PageLinkController _pageLinkController = PageLinkController(); final PageLinkController _pageLinkController = PageLinkController();

View File

@@ -5,7 +5,7 @@ import 'package:thingsboard_app/core/entity/entities_base.dart';
import 'tenants_list.dart'; import 'tenants_list.dart';
class TenantsWidget extends TbContextWidget<TenantsWidget, _TenantsWidgetState> { class TenantsWidget extends TbContextWidget {
TenantsWidget(TbContext tbContext) : super(tbContext); TenantsWidget(TbContext tbContext) : super(tbContext);
@@ -14,7 +14,7 @@ class TenantsWidget extends TbContextWidget<TenantsWidget, _TenantsWidgetState>
} }
class _TenantsWidgetState extends TbContextState<TenantsWidget, _TenantsWidgetState> { class _TenantsWidgetState extends TbContextState<TenantsWidget> {
final PageLinkController _pageLinkController = PageLinkController(); final PageLinkController _pageLinkController = PageLinkController();

View File

@@ -0,0 +1,3 @@
import 'package:thingsboard_client/thingsboard_client.dart';
TbStorage createAppStorage() => throw UnsupportedError('');

View File

@@ -0,0 +1,3 @@
export '_tb_app_storage.dart'
if (dart.library.io) 'tb_secure_storage.dart'
if (dart.library.html) 'tb_web_local_storage.dart';

View File

@@ -1,6 +1,8 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:thingsboard_client/thingsboard_client.dart'; import 'package:thingsboard_client/thingsboard_client.dart';
TbStorage createAppStorage() => TbSecureStorage();
class TbSecureStorage implements TbStorage { class TbSecureStorage implements TbStorage {
final flutterStorage = FlutterSecureStorage(); final flutterStorage = FlutterSecureStorage();

View File

@@ -0,0 +1,25 @@
import 'package:thingsboard_client/thingsboard_client.dart';
import 'dart:html';
TbStorage createAppStorage() => TbWebLocalStorage();
class TbWebLocalStorage implements TbStorage {
final Storage _localStorage = window.localStorage;
@override
Future<void> deleteItem(String key) async {
_localStorage.remove(key);
}
@override
Future<String?> getItem(String key) async {
return _localStorage[key];
}
@override
Future<void> setItem(String key, String value) async {
_localStorage[key] = value;
}
}

View File

@@ -7,7 +7,7 @@ import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:thingsboard_app/core/context/tb_context.dart'; import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart'; import 'package:thingsboard_app/core/context/tb_context_widget.dart';
class QrCodeScannerPage extends TbPageWidget<QrCodeScannerPage, _QrCodeScannerPageState> { class QrCodeScannerPage extends TbPageWidget {
QrCodeScannerPage(TbContext tbContext) : super(tbContext); QrCodeScannerPage(TbContext tbContext) : super(tbContext);
@@ -16,7 +16,7 @@ class QrCodeScannerPage extends TbPageWidget<QrCodeScannerPage, _QrCodeScannerPa
} }
class _QrCodeScannerPageState extends TbPageState<QrCodeScannerPage, _QrCodeScannerPageState> { class _QrCodeScannerPageState extends TbPageState<QrCodeScannerPage> {
Timer? simulatedQrTimer; Timer? simulatedQrTimer;
QRViewController? controller; QRViewController? controller;

View File

@@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart';
import 'package:thingsboard_app/core/context/tb_context.dart'; import 'package:thingsboard_app/core/context/tb_context.dart';
import 'package:thingsboard_app/core/context/tb_context_widget.dart'; import 'package:thingsboard_app/core/context/tb_context_widget.dart';
class TbAppBar extends TbContextWidget<TbAppBar, _TbAppBarState> implements PreferredSizeWidget { class TbAppBar extends TbContextWidget implements PreferredSizeWidget {
final Widget? leading; final Widget? leading;
final Widget? title; final Widget? title;
@@ -28,7 +28,7 @@ class TbAppBar extends TbContextWidget<TbAppBar, _TbAppBarState> implements Pref
} }
class _TbAppBarState extends TbContextState<TbAppBar, _TbAppBarState> { class _TbAppBarState extends TbContextState<TbAppBar> {
@override @override
void initState() { void initState() {
@@ -74,7 +74,7 @@ class _TbAppBarState extends TbContextState<TbAppBar, _TbAppBarState> {
} }
} }
class TbAppSearchBar extends TbContextWidget<TbAppSearchBar, _TbAppSearchBarState> implements PreferredSizeWidget { class TbAppSearchBar extends TbContextWidget implements PreferredSizeWidget {
final double? elevation; final double? elevation;
final Color? shadowColor; final Color? shadowColor;
@@ -94,7 +94,7 @@ class TbAppSearchBar extends TbContextWidget<TbAppSearchBar, _TbAppSearchBarStat
_TbAppSearchBarState createState() => _TbAppSearchBarState(); _TbAppSearchBarState createState() => _TbAppSearchBarState();
} }
class _TbAppSearchBarState extends TbContextState<TbAppSearchBar, _TbAppSearchBarState> { class _TbAppSearchBarState extends TbContextState<TbAppSearchBar> {
final TextEditingController _filter = new TextEditingController(); final TextEditingController _filter = new TextEditingController();
final _textUpdates = StreamController<String>(); final _textUpdates = StreamController<String>();

View File

@@ -488,6 +488,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
universal_platform:
dependency: "direct main"
description:
name: universal_platform
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0+1"
url_launcher: url_launcher:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -38,6 +38,7 @@ dependencies:
dart_jsonwebtoken: ^2.2.0 dart_jsonwebtoken: ^2.2.0
crypto: ^3.0.1 crypto: ^3.0.1
flutter_form_builder: ^6.0.1 flutter_form_builder: ^6.0.1
universal_platform: ^1.0.0+1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: