Add flutter 3+ support. Update dependencies. Fix code style and format issues.
This commit is contained in:
@@ -2,7 +2,6 @@ import 'dart:async';
|
||||
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:thingsboard_app/constants/assets_path.dart';
|
||||
import 'package:thingsboard_app/core/context/tb_context.dart';
|
||||
@@ -14,7 +13,6 @@ import 'package:thingsboard_app/utils/utils.dart';
|
||||
import 'package:thingsboard_client/thingsboard_client.dart';
|
||||
|
||||
mixin DeviceProfilesBase on EntitiesBase<DeviceProfileInfo, PageLink> {
|
||||
|
||||
final RefreshDeviceCounts refreshDeviceCounts = RefreshDeviceCounts();
|
||||
|
||||
@override
|
||||
@@ -48,7 +46,8 @@ mixin DeviceProfilesBase on EntitiesBase<DeviceProfileInfo, PageLink> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildEntityGridCard(BuildContext context, DeviceProfileInfo deviceProfile) {
|
||||
Widget buildEntityGridCard(
|
||||
BuildContext context, DeviceProfileInfo deviceProfile) {
|
||||
return DeviceProfileCard(tbContext, deviceProfile);
|
||||
}
|
||||
|
||||
@@ -56,7 +55,6 @@ mixin DeviceProfilesBase on EntitiesBase<DeviceProfileInfo, PageLink> {
|
||||
double? gridChildAspectRatio() {
|
||||
return 156 / 200;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RefreshDeviceCounts {
|
||||
@@ -64,20 +62,20 @@ class RefreshDeviceCounts {
|
||||
}
|
||||
|
||||
class AllDevicesCard extends TbContextWidget {
|
||||
|
||||
final RefreshDeviceCounts refreshDeviceCounts;
|
||||
|
||||
AllDevicesCard(TbContext tbContext, this.refreshDeviceCounts) : super(tbContext);
|
||||
AllDevicesCard(TbContext tbContext, this.refreshDeviceCounts)
|
||||
: super(tbContext);
|
||||
|
||||
@override
|
||||
_AllDevicesCardState createState() => _AllDevicesCardState();
|
||||
|
||||
}
|
||||
|
||||
class _AllDevicesCardState extends TbContextState<AllDevicesCard> {
|
||||
|
||||
final StreamController<int?> _activeDevicesCount = StreamController.broadcast();
|
||||
final StreamController<int?> _inactiveDevicesCount = StreamController.broadcast();
|
||||
final StreamController<int?> _activeDevicesCount =
|
||||
StreamController.broadcast();
|
||||
final StreamController<int?> _inactiveDevicesCount =
|
||||
StreamController.broadcast();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -103,9 +101,12 @@ class _AllDevicesCardState extends TbContextState<AllDevicesCard> {
|
||||
Future<void> _countDevices() {
|
||||
_activeDevicesCount.add(null);
|
||||
_inactiveDevicesCount.add(null);
|
||||
Future<int> activeDevicesCount = EntityQueryApi.countDevices(tbClient, active: true);
|
||||
Future<int> inactiveDevicesCount = EntityQueryApi.countDevices(tbClient, active: false);
|
||||
Future<List<int>> countsFuture = Future.wait([activeDevicesCount, inactiveDevicesCount]);
|
||||
Future<int> activeDevicesCount =
|
||||
EntityQueryApi.countDevices(tbClient, active: true);
|
||||
Future<int> inactiveDevicesCount =
|
||||
EntityQueryApi.countDevices(tbClient, active: false);
|
||||
Future<List<int>> countsFuture =
|
||||
Future.wait([activeDevicesCount, inactiveDevicesCount]);
|
||||
countsFuture.then((counts) {
|
||||
if (this.mounted) {
|
||||
_activeDevicesCount.add(counts[0]);
|
||||
@@ -117,20 +118,19 @@ class _AllDevicesCardState extends TbContextState<AllDevicesCard> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child:
|
||||
Container(
|
||||
child: Card(
|
||||
margin: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
elevation: 0,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(padding: EdgeInsets.fromLTRB(16, 12, 16, 15),
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Container(
|
||||
child: Card(
|
||||
margin: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
elevation: 0,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(16, 12, 16, 15),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@@ -139,120 +139,126 @@ class _AllDevicesCardState extends TbContextState<AllDevicesCard> {
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
height: 20 / 14
|
||||
)
|
||||
),
|
||||
height: 20 / 14)),
|
||||
Icon(Icons.arrow_forward, size: 18)
|
||||
],
|
||||
)
|
||||
),
|
||||
Divider(height: 1),
|
||||
Padding(padding: EdgeInsets.all(0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(fit: FlexFit.tight,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Container(
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: StreamBuilder<int?>(
|
||||
stream: _activeDevicesCount.stream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(context, true, deviceCount);
|
||||
} else {
|
||||
return Center(child:
|
||||
Container(height: 20, width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(tbContext.currentState!.context).colorScheme.primary),
|
||||
strokeWidth: 2.5)));
|
||||
}
|
||||
},
|
||||
)
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList?active=true');
|
||||
}
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 4),
|
||||
Container(width: 1,
|
||||
height: 40,
|
||||
child: VerticalDivider(width: 1)
|
||||
),
|
||||
Flexible(fit: FlexFit.tight,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Container(
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: StreamBuilder<int?>(
|
||||
stream: _inactiveDevicesCount.stream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(context, false, deviceCount);
|
||||
} else {
|
||||
return Center(child:
|
||||
Container(height: 20, width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(tbContext.currentState!.context).colorScheme.primary),
|
||||
strokeWidth: 2.5)));
|
||||
}
|
||||
},
|
||||
)
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList?active=false');
|
||||
}
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withAlpha((255 * 0.05).ceil()),
|
||||
blurRadius: 6.0,
|
||||
offset: Offset(0, 4)
|
||||
)
|
||||
],
|
||||
),
|
||||
)),
|
||||
Divider(height: 1),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(
|
||||
fit: FlexFit.tight,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Container(
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: StreamBuilder<int?>(
|
||||
stream: _activeDevicesCount.stream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(
|
||||
context, true, deviceCount);
|
||||
} else {
|
||||
return Center(
|
||||
child: Container(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
valueColor:
|
||||
AlwaysStoppedAnimation(
|
||||
Theme.of(tbContext
|
||||
.currentState!
|
||||
.context)
|
||||
.colorScheme
|
||||
.primary),
|
||||
strokeWidth: 2.5)));
|
||||
}
|
||||
},
|
||||
)),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList?active=true');
|
||||
}),
|
||||
),
|
||||
// SizedBox(width: 4),
|
||||
Container(
|
||||
width: 1,
|
||||
height: 40,
|
||||
child: VerticalDivider(width: 1)),
|
||||
Flexible(
|
||||
fit: FlexFit.tight,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Container(
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: StreamBuilder<int?>(
|
||||
stream: _inactiveDevicesCount.stream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(
|
||||
context, false, deviceCount);
|
||||
} else {
|
||||
return Center(
|
||||
child: Container(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
valueColor:
|
||||
AlwaysStoppedAnimation(
|
||||
Theme.of(tbContext
|
||||
.currentState!
|
||||
.context)
|
||||
.colorScheme
|
||||
.primary),
|
||||
strokeWidth: 2.5)));
|
||||
}
|
||||
},
|
||||
)),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList?active=false');
|
||||
}),
|
||||
)
|
||||
],
|
||||
))
|
||||
],
|
||||
)),
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withAlpha((255 * 0.05).ceil()),
|
||||
blurRadius: 6.0,
|
||||
offset: Offset(0, 4))
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList');
|
||||
}
|
||||
);
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DeviceProfileCard extends TbContextWidget {
|
||||
|
||||
final DeviceProfileInfo deviceProfile;
|
||||
|
||||
DeviceProfileCard(TbContext tbContext, this.deviceProfile) : super(tbContext);
|
||||
|
||||
@override
|
||||
_DeviceProfileCardState createState() => _DeviceProfileCardState();
|
||||
|
||||
}
|
||||
|
||||
class _DeviceProfileCardState extends TbContextState<DeviceProfileCard> {
|
||||
|
||||
late Future<int> activeDevicesCount;
|
||||
late Future<int> inactiveDevicesCount;
|
||||
|
||||
@@ -269,8 +275,10 @@ class _DeviceProfileCardState extends TbContextState<DeviceProfileCard> {
|
||||
}
|
||||
|
||||
_countDevices() {
|
||||
activeDevicesCount = EntityQueryApi.countDevices(tbClient, deviceType: widget.deviceProfile.name, active: true);
|
||||
inactiveDevicesCount = EntityQueryApi.countDevices(tbClient, deviceType: widget.deviceProfile.name, active: false);
|
||||
activeDevicesCount = EntityQueryApi.countDevices(tbClient,
|
||||
deviceType: widget.deviceProfile.name, active: true);
|
||||
inactiveDevicesCount = EntityQueryApi.countDevices(tbClient,
|
||||
deviceType: widget.deviceProfile.name, active: false);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -292,99 +300,95 @@ class _DeviceProfileCardState extends TbContextState<DeviceProfileCard> {
|
||||
imageFit = BoxFit.cover;
|
||||
padding = 0;
|
||||
}
|
||||
return
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Stack (
|
||||
children: [
|
||||
SizedBox.expand(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(padding),
|
||||
child: FittedBox(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
fit: imageFit,
|
||||
child: image
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
Container(
|
||||
height: 44,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6),
|
||||
child: Center(
|
||||
child: AutoSizeText(entity.name,
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
minFontSize: 12,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
height: 20 / 14
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Divider(height: 1),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: FutureBuilder<int>(
|
||||
future: activeDevicesCount,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData && snapshot.connectionState == ConnectionState.done) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(context, true, deviceCount);
|
||||
} else {
|
||||
return Container(height: 40,
|
||||
child: Center(
|
||||
child: Container(
|
||||
height: 20, width: 20,
|
||||
child:
|
||||
CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(tbContext.currentState!.context).colorScheme.primary),
|
||||
strokeWidth: 2.5))));
|
||||
}
|
||||
},
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList?active=true&deviceType=${entity.name}');
|
||||
}
|
||||
),
|
||||
Divider(height: 1),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: FutureBuilder<int>(
|
||||
future: inactiveDevicesCount,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData && snapshot.connectionState == ConnectionState.done) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(context, false, deviceCount);
|
||||
} else {
|
||||
return Container(height: 40,
|
||||
child: Center(
|
||||
child: Container(
|
||||
height: 20, width: 20,
|
||||
child:
|
||||
CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(tbContext.currentState!.context).colorScheme.primary),
|
||||
strokeWidth: 2.5))));
|
||||
}
|
||||
},
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList?active=false&deviceType=${entity.name}');
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: Column(children: [
|
||||
Expanded(
|
||||
child: Stack(children: [
|
||||
SizedBox.expand(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(padding),
|
||||
child: FittedBox(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
fit: imageFit,
|
||||
child: image)))
|
||||
])),
|
||||
Container(
|
||||
height: 44,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6),
|
||||
child: Center(
|
||||
child: AutoSizeText(
|
||||
entity.name,
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
minFontSize: 12,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
height: 20 / 14),
|
||||
)))),
|
||||
Divider(height: 1),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: FutureBuilder<int>(
|
||||
future: activeDevicesCount,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData &&
|
||||
snapshot.connectionState == ConnectionState.done) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(context, true, deviceCount);
|
||||
} else {
|
||||
return Container(
|
||||
height: 40,
|
||||
child: Center(
|
||||
child: Container(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(
|
||||
tbContext.currentState!.context)
|
||||
.colorScheme
|
||||
.primary),
|
||||
strokeWidth: 2.5))));
|
||||
}
|
||||
},
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo('/deviceList?active=true&deviceType=${entity.name}');
|
||||
}),
|
||||
Divider(height: 1),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: FutureBuilder<int>(
|
||||
future: inactiveDevicesCount,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData &&
|
||||
snapshot.connectionState == ConnectionState.done) {
|
||||
var deviceCount = snapshot.data!;
|
||||
return _buildDeviceCount(context, false, deviceCount);
|
||||
} else {
|
||||
return Container(
|
||||
height: 40,
|
||||
child: Center(
|
||||
child: Container(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(
|
||||
tbContext.currentState!.context)
|
||||
.colorScheme
|
||||
.primary),
|
||||
strokeWidth: 2.5))));
|
||||
}
|
||||
},
|
||||
),
|
||||
onTap: () {
|
||||
navigateTo(
|
||||
'/deviceList?active=false&deviceType=${entity.name}');
|
||||
})
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,26 +406,27 @@ Widget _buildDeviceCount(BuildContext context, bool active, int count) {
|
||||
Stack(
|
||||
children: [
|
||||
Icon(Icons.devices_other, size: 16, color: color),
|
||||
if (!active) CustomPaint(
|
||||
size: Size.square(16),
|
||||
painter: StrikeThroughPainter(color: color, offset: 2),
|
||||
)
|
||||
if (!active)
|
||||
CustomPaint(
|
||||
size: Size.square(16),
|
||||
painter: StrikeThroughPainter(color: color, offset: 2),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(width: 8.67),
|
||||
Text(active ? 'Active' : 'Inactive', style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 16 / 12,
|
||||
color: color
|
||||
)),
|
||||
SizedBox(width: 8.67),
|
||||
Text(count.toString(), style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 16 / 12,
|
||||
color: color
|
||||
))
|
||||
SizedBox(width: 8.67),
|
||||
Text(active ? 'Active' : 'Inactive',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 16 / 12,
|
||||
color: color)),
|
||||
SizedBox(width: 8.67),
|
||||
Text(count.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 16 / 12,
|
||||
color: color))
|
||||
],
|
||||
),
|
||||
Icon(Icons.chevron_right, size: 16, color: Color(0xFFACACAC))
|
||||
@@ -431,7 +436,6 @@ Widget _buildDeviceCount(BuildContext context, bool active, int count) {
|
||||
}
|
||||
|
||||
class StrikeThroughPainter extends CustomPainter {
|
||||
|
||||
final Color color;
|
||||
final double offset;
|
||||
|
||||
@@ -441,7 +445,8 @@ class StrikeThroughPainter extends CustomPainter {
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()..color = color;
|
||||
paint.strokeWidth = 1.5;
|
||||
canvas.drawLine(Offset(offset, offset), Offset(size.width - offset, size.height - offset), paint);
|
||||
canvas.drawLine(Offset(offset, offset),
|
||||
Offset(size.width - offset, size.height - offset), paint);
|
||||
paint.color = Colors.white;
|
||||
canvas.drawLine(Offset(2, 0), Offset(size.width + 2, size.height), paint);
|
||||
}
|
||||
@@ -450,5 +455,4 @@ class StrikeThroughPainter extends CustomPainter {
|
||||
bool shouldRepaint(covariant StrikeThroughPainter oldDelegate) {
|
||||
return color != oldDelegate.color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user