Compare commits

..

6 Commits

12 changed files with 117 additions and 167 deletions

View File

@ -1,6 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart';
@ -31,7 +29,7 @@ class SixSceneScreen extends StatelessWidget {
..add(const SexSceneSwitchInitial()),
child: BlocBuilder<SixSceneBloc, SixSceneState>(
builder: (context, state) {
final _bloc = BlocProvider.of<SixSceneBloc>(context);
final bloc = BlocProvider.of<SixSceneBloc>(context);
SixSceneModel model = SixSceneModel(
scene_1: '',
scene_2: '',
@ -48,7 +46,7 @@ class SixSceneScreen extends StatelessWidget {
model = state.device;
}
return DefaultScaffold(
title: _bloc.deviceInfo.name,
title: device?.name ?? '6 Scene Switch',
actions: [
InkWell(
onTap: () async {
@ -58,9 +56,9 @@ class SixSceneScreen extends StatelessWidget {
),
);
if (val == null) {
_bloc.add(const SixSceneInitialInfo());
_bloc.add(const SixSceneInitial());
_bloc.add(const SexSceneSwitchInitial());
bloc.add(const SixSceneInitialInfo());
bloc.add(const SixSceneInitial());
bloc.add(const SexSceneSwitchInitial());
}
},
child: SvgPicture.asset(Assets.assetsIconsSettings),
@ -77,7 +75,7 @@ class SixSceneScreen extends StatelessWidget {
)
: RefreshIndicator(
onRefresh: () async {
_bloc.add(const SixSceneInitial());
bloc.add(const SixSceneInitial());
},
child: ListView(
children: [
@ -92,22 +90,22 @@ class SixSceneScreen extends StatelessWidget {
switch4Title: model.scene_4,
switch5Title: model.scene_5,
switch6Title: model.scene_6,
switch1Down: _bloc.deviceStatus.switch_backlight
switch1Down: bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch1Up: _bloc.deviceStatus.switch_backlight
switch1Up: bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch2Down: _bloc.deviceStatus.switch_backlight
switch2Down: bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch2Up: _bloc.deviceStatus.switch_backlight
switch2Up: bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch3Up: _bloc.deviceStatus.switch_backlight
switch3Up: bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch3Down: _bloc.deviceStatus.switch_backlight
switch3Down: bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
onSwitch3DownTap: () {
@ -135,7 +133,7 @@ class SixSceneScreen extends StatelessWidget {
Expanded(
child: DefaultContainer(
onTap: () {
_bloc.add(ChangeSwitchStatusEvent());
bloc.add(ChangeSwitchStatusEvent());
},
child: Column(
crossAxisAlignment:
@ -197,9 +195,9 @@ class SixSceneScreen extends StatelessWidget {
);
if (value == true) {
Future.delayed(
const Duration(
milliseconds: 200), () {
_bloc.add(
const Duration(milliseconds: 200),
() {
bloc.add(
const SexSceneSwitchInitial());
});
}

View File

@ -22,14 +22,15 @@ class DoorSensorScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Door Sensor',
title: device?.name,
child: BlocProvider(
create: (context) =>
DoorSensorBloc(DSId: device?.uuid ?? '')..add(const DoorSensorInitial()),
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
builder: (context, state) {
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
DoorSensorModel model = DoorSensorModel(batteryPercentage: 0, doorContactState: false);
DoorSensorModel model =
DoorSensorModel(batteryPercentage: 0, doorContactState: false);
if (state is LoadingNewSate) {
model = state.doorSensor;
} else if (state is UpdateState) {
@ -37,8 +38,8 @@ class DoorSensorScreen extends StatelessWidget {
}
return state is DoorSensorLoadingState
? const Center(
child:
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
child: DefaultContainer(
width: 50, height: 50, child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
@ -56,7 +57,8 @@ class DoorSensorScreen extends StatelessWidget {
Expanded(
flex: 4,
child: InkWell(
overlayColor: WidgetStateProperty.all(Colors.transparent),
overlayColor:
WidgetStateProperty.all(Colors.transparent),
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
@ -107,17 +109,21 @@ class DoorSensorScreen extends StatelessWidget {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
DoorRecordsScreen(DSId: device!.uuid!)),
DoorRecordsScreen(
DSId: device!.uuid!)),
);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints:
const BoxConstraints(maxHeight: 46, maxWidth: 50),
child: SvgPicture.asset(Assets.doorRecordsIcon),
constraints: const BoxConstraints(
maxHeight: 46, maxWidth: 50),
child: SvgPicture.asset(
Assets.doorRecordsIcon),
),
const SizedBox(
height: 15,
@ -143,18 +149,21 @@ class DoorSensorScreen extends StatelessWidget {
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => NotificationSettingsPage()),
builder: (context) =>
NotificationSettingsPage()),
);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints:
const BoxConstraints(maxHeight: 46, maxWidth: 50),
child:
SvgPicture.asset(Assets.doorNotificationSetting),
constraints: const BoxConstraints(
maxHeight: 46, maxWidth: 50),
child: SvgPicture.asset(
Assets.doorNotificationSetting),
),
const SizedBox(
height: 15,

View File

@ -47,7 +47,7 @@ class FourSceneScreen extends StatelessWidget {
}
return DefaultScaffold(
title: _bloc.deviceInfo.name,
title: device?.name ?? '4 Scene',
actions: [
InkWell(
onTap: () async {
@ -165,7 +165,7 @@ class FourSceneScreen extends StatelessWidget {
Navigator.of(context).pop();
},
confirmTab:
(switchSelected) async {
(switchSelected) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>

View File

@ -21,7 +21,8 @@ class GateWayView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => GatewayBloc()..add(GatewayInitial(gatewayId: gatewayObj.uuid ?? '')),
create: (context) =>
GatewayBloc()..add(GatewayInitial(gatewayId: gatewayObj.uuid ?? '')),
child: BlocBuilder<GatewayBloc, GatewayState>(builder: (context, state) {
List<DeviceModel> devicesList = [];
if (state is UpdateGatewayState) {
@ -37,7 +38,7 @@ class GateWayView extends StatelessWidget {
extendBodyBehindAppBar: true,
extendBody: true,
appBar: DeviceAppbar(
deviceName: 'Gateway',
deviceName: gatewayObj.name ?? 'Gateway',
deviceUuid: gatewayObj.uuid!,
),
body: Container(
@ -60,7 +61,7 @@ class GateWayView extends StatelessWidget {
},
child: ListView(
children: [
Container(
SizedBox(
height: MediaQuery.of(context).size.height,
child: SafeArea(
child: Column(
@ -90,7 +91,8 @@ class GateWayView extends StatelessWidget {
),
]),
),
if (devicesList.isEmpty && state is UpdateGatewayState)
if (devicesList.isEmpty &&
state is UpdateGatewayState)
Container(
width: MediaQuery.sizeOf(context).width,
alignment: AlignmentDirectional.center,
@ -115,7 +117,8 @@ class GateWayView extends StatelessWidget {
margin: const EdgeInsets.only(top: 20),
height: 50,
width: 50,
child: const RefreshProgressIndicator()),
child:
const RefreshProgressIndicator()),
)
: Expanded(
child: GridView.builder(
@ -130,7 +133,8 @@ class GateWayView extends StatelessWidget {
shrinkWrap: true,
itemCount: devicesList.length,
itemBuilder: (context, index) {
return RoomPageSwitch(device: devicesList[index]);
return RoomPageSwitch(
device: devicesList[index]);
},
),
)

View File

@ -51,7 +51,7 @@ class _PowerClampPageState extends State<PowerClampPage> {
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Power Clamp',
title: widget.device?.name ?? 'Power Clamp',
child: BlocProvider(
create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
..add(const PowerClampInitial()),
@ -153,41 +153,6 @@ class _PowerClampPageState extends State<PowerClampPage> {
];
}
List<Widget> _buildPowerClampCards(PowerClampModel model,
List<EnergyData> chartData, PowerClampBloc blocProvider) {
return [
_buildPowerClampCard(
phaseType: '',
title: 'Total Energy \nConsumption',
phase: model.status.general,
isGeneral: true,
chartData: chartData,
blocProvider: blocProvider,
),
_buildPowerClampCard(
phaseType: 'Phase A consumption',
title: 'Phase A Energy \nConsumption',
phase: model.status.phaseA,
chartData: chartData,
blocProvider: blocProvider,
),
_buildPowerClampCard(
phaseType: 'Phase B consumption',
title: 'Phase B Energy \nConsumption',
phase: model.status.phaseB,
chartData: chartData,
blocProvider: blocProvider,
),
_buildPowerClampCard(
phaseType: 'Phase C consumption',
title: 'Phase C Energy \nConsumption',
phase: model.status.phaseC,
chartData: chartData,
blocProvider: blocProvider,
),
];
}
Widget _buildPowerClampCard({
required String title,
required String phaseType,
@ -209,10 +174,8 @@ class _PowerClampPageState extends State<PowerClampPage> {
blocProvider.add(SelectDateEvent(context: context));
},
totalActiveGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
totalCurrentGeneral:
isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
totalFrequencyGeneral:
isGeneral ? _getValueOrNA(phase.dataPoints, 4) : null,
totalCurrentGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
totalFrequencyGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 4) : null,
totalFactor: !isGeneral ? _getValueOrNA(phase.dataPoints, 3) : null,
totalActive: !isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
totalCurrent: !isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
@ -223,9 +186,7 @@ class _PowerClampPageState extends State<PowerClampPage> {
}
String _getValueOrNA(List<DataPoint> dataPoints, int index) {
return dataPoints.length > index
? dataPoints[index].value.toString()
: 'N/A';
return dataPoints.length > index ? dataPoints[index].value.toString() : 'N/A';
}
Widget _buildPageIndicator() {
@ -240,8 +201,7 @@ class _PowerClampPageState extends State<PowerClampPage> {
height: 10.0,
width: _currentPage == index ? 10.0 : 10.0,
decoration: BoxDecoration(
color:
_currentPage == index ? Colors.grey : ColorsManager.greyColor,
color: _currentPage == index ? Colors.grey : ColorsManager.greyColor,
borderRadius: BorderRadius.circular(5.0),
),
);

View File

@ -10,6 +10,7 @@ import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/door_sensor/door_sensor_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart';
@ -19,14 +20,13 @@ import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/one_touch/one_touch_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/three_touch/three_touch_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_Interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/water_heater/water_heater_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/water_leak/water_leak_screen.dart';
import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
@ -73,48 +73,31 @@ class RoomPageSwitch extends StatelessWidget {
? CustomSwitch(
device: device,
)
: const SizedBox(),
: const SizedBox.shrink(),
],
),
LayoutBuilder(
builder: (context, constraints) {
final text = device.name ?? "";
final textPainter = TextPainter(
text: TextSpan(
text: text,
style: context.bodyLarge.copyWith(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.grey,
),
),
maxLines: 1,
textDirection: TextDirection.ltr,
);
textPainter.layout(maxWidth: constraints.maxWidth);
final exceeded = textPainter.didExceedMaxLines;
return Text(
exceeded ? '${text.substring(0, 10)}...' : text,
style: context.bodyLarge.copyWith(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.grey,
),
overflow: TextOverflow.clip,
maxLines: 1,
);
},
),
Text(
device.subspace!.subspaceName ?? '',
overflow: TextOverflow.ellipsis,
style: context.bodySmall.copyWith(
fontWeight: FontWeight.w400,
fontSize: 10,
device.name ?? '',
textScaler: TextScaler.linear(1),
style: context.bodyLarge.copyWith(
fontWeight: FontWeight.bold,
color: Colors.grey,
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
FittedBox(
fit: BoxFit.scaleDown,
child: Text(
device.subspace!.subspaceName ?? '',
overflow: TextOverflow.ellipsis,
textScaler: TextScaler.linear(1),
style: context.bodySmall.copyWith(
fontWeight: FontWeight.w400,
fontSize: 9,
color: Colors.grey,
),
),
),
],
@ -132,7 +115,6 @@ Future<void> showDeviceInterface(
required BuildContext context,
required isAllDevices,
List<DeviceModel>? allDevices}) async {
final devicesCubit = context.read<DevicesCubit>();
switch (device.productType) {

View File

@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_alarm_management_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_records_screen.dart';
@ -29,17 +28,8 @@ class SosScreen extends StatelessWidget {
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model = SosModel(
batteryPercentage: 0,
sosContactState: '',
);
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return DefaultScaffold(
title: sensor.deviceInfo.name,
title: device?.name,
actions: [
InkWell(
onTap: () async {
@ -82,38 +72,33 @@ class SosScreen extends StatelessWidget {
Expanded(
flex: 4,
child: InkWell(
overlayColor: MaterialStateProperty.all(
Colors.transparent),
overlayColor:
WidgetStateProperty.all(Colors.transparent),
onTap: () {
// Add functionality for the main SOS button here
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(890),
borderRadius: BorderRadius.circular(890),
boxShadow: [
BoxShadow(
color:
Colors.white.withOpacity(0.1),
color: Colors.white.withOpacity(0.1),
blurRadius: 24,
offset: const Offset(-5, -5),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.black
.withOpacity(0.11),
color: Colors.black.withOpacity(0.11),
blurRadius: 25,
offset: const Offset(5, 5),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.black
.withOpacity(0.13),
color: Colors.black.withOpacity(0.13),
blurRadius: 30,
offset: const Offset(5, 5),
blurStyle: BlurStyle.inner,
@ -140,9 +125,8 @@ class SosScreen extends StatelessWidget {
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
SosRecordsScreen(
sosId: device!.uuid!),
builder: (context) => SosRecordsScreen(
sosId: device!.uuid!),
),
);
},
@ -197,8 +181,8 @@ class SosScreen extends StatelessWidget {
maxHeight: 46,
maxWidth: 50,
),
child: SvgPicture.asset(Assets
.doorNotificationSetting),
child: SvgPicture.asset(
Assets.doorNotificationSetting),
),
const SizedBox(height: 15),
const Flexible(

View File

@ -9,7 +9,10 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class GangSwitch extends StatelessWidget {
const GangSwitch(
{super.key, required this.threeGangSwitch, required this.value, required this.action});
{super.key,
required this.threeGangSwitch,
required this.value,
required this.action});
final DeviceModel threeGangSwitch;
final bool value;

View File

@ -21,7 +21,7 @@ class WaterHeaterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Water heater',
title: device?.name?? 'Water heater',
child: BlocProvider(
create: (context) => WaterHeaterBloc(switchCode: 'switch_1', whId: device?.uuid ?? '')
..add(const WaterHeaterInitial()),

View File

@ -22,7 +22,7 @@ class WaterLeakScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Water Leak Sensor',
title: device?.name ?? 'Water Leak',
child: BlocProvider(
create: (context) => WaterLeakBloc(WLId: device?.uuid ?? '')
..add(const WaterLeakInitial()),

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
@ -7,6 +8,8 @@ import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/function_model.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import '../../features/devices/model/create_temporary_password_model.dart';
class DevicesAPI {
@ -99,7 +102,7 @@ class DevicesAPI {
static Future<Map<String, dynamic>> getPowerClampStatus(
String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{powerClampUuid}', deviceId),
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -580,7 +583,7 @@ class DevicesAPI {
path: path,
showServerMessage: false,
expectedResponseModel: (json) {
final data = json['data'];
final data = json['data'] as List<dynamic>?;
if (data == null || data.isEmpty) {
return <DeviceModel>[];
@ -588,9 +591,14 @@ class DevicesAPI {
if (json == null || json.isEmpty || json == []) {
return <DeviceModel>[];
}
return data
.map<DeviceModel>((device) => DeviceModel.fromJson(device))
.toList();
final result = <DeviceModel>[];
for (final device in data) {
final mappedDevice = DeviceModel.fromJson(device);
if (mappedDevice.productType?.name != DeviceType.FlushMountedSensor.name) {
result.add(mappedDevice);
}
}
return result;
},
);

View File

@ -62,6 +62,7 @@ enum DeviceType {
SixScene,
SOS,
Other,
FlushMountedSensor,
}
enum FunctionType { Boolean, Enum, Integer, Raw, String }
@ -96,6 +97,7 @@ Map<String, DeviceType> devicesTypesMap = {
"4S": DeviceType.FourScene,
"6S": DeviceType.SixScene,
"SOS": DeviceType.SOS,
"NCPS": DeviceType.FlushMountedSensor,
};
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {