mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
push 1G , 2G glass switches
This commit is contained in:
@ -2,11 +2,11 @@ import 'package:flutter/gestures.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:syncrow_web/services/locator.dart';
|
import 'package:syncrow_web/services/locator.dart';
|
||||||
import 'package:syncrow_web/utils/app_routes.dart';
|
import 'package:syncrow_web/utils/app_routes.dart';
|
||||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
||||||
@ -14,8 +14,7 @@ import 'package:syncrow_web/utils/theme/theme.dart';
|
|||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
try {
|
try {
|
||||||
const environment =
|
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
||||||
String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
|
||||||
await dotenv.load(fileName: '.env.$environment');
|
await dotenv.load(fileName: '.env.$environment');
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
initialSetup();
|
initialSetup();
|
||||||
@ -45,11 +44,9 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
//HomeBloc.fetchUserInfo();
|
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||||
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
|
||||||
BlocProvider<VisitorPasswordBloc>(
|
BlocProvider<VisitorPasswordBloc>(
|
||||||
create: (context) => VisitorPasswordBloc(),
|
create: (context) => VisitorPasswordBloc(),
|
||||||
)
|
)
|
||||||
|
@ -13,10 +13,13 @@ import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_batch_co
|
|||||||
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart';
|
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart';
|
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart';
|
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart';
|
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_device_control.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_device_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart';
|
||||||
@ -24,6 +27,8 @@ import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_
|
|||||||
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_batch_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_device_control.dart';
|
||||||
|
|
||||||
|
import '../../one_g_glass_switch/view/one_gang_glass_switch_control_view.dart';
|
||||||
|
|
||||||
mixin RouteControlsBasedCode {
|
mixin RouteControlsBasedCode {
|
||||||
Widget routeControlsWidgets({required AllDevicesModel device}) {
|
Widget routeControlsWidgets({required AllDevicesModel device}) {
|
||||||
switch (device.productType) {
|
switch (device.productType) {
|
||||||
@ -39,6 +44,18 @@ mixin RouteControlsBasedCode {
|
|||||||
return LivingRoomDeviceControlsView(
|
return LivingRoomDeviceControlsView(
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
);
|
);
|
||||||
|
case '1GT':
|
||||||
|
return OneGangGlassSwitchControlView(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
);
|
||||||
|
case '2GT':
|
||||||
|
return TwoGangGlassSwitchControlView(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
);
|
||||||
|
// case '3GT':
|
||||||
|
// return LivingRoomClassSwitchControlView(
|
||||||
|
// deviceId: device.uuid!,
|
||||||
|
// );
|
||||||
case 'GW':
|
case 'GW':
|
||||||
return GateWayControlsView(
|
return GateWayControlsView(
|
||||||
gatewayId: device.uuid!,
|
gatewayId: device.uuid!,
|
||||||
@ -86,77 +103,52 @@ mixin RouteControlsBasedCode {
|
|||||||
switch (devices.first.productType) {
|
switch (devices.first.productType) {
|
||||||
case '1G':
|
case '1G':
|
||||||
return WallLightBatchControlView(
|
return WallLightBatchControlView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == '1G')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == '1G'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case '2G':
|
case '2G':
|
||||||
return TwoGangBatchControlView(
|
return TwoGangBatchControlView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == '2G')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == '2G'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case '3G':
|
case '3G':
|
||||||
return LivingRoomBatchControlsView(
|
return LivingRoomBatchControlsView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == '3G')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == '3G'))
|
);
|
||||||
.map((e) => e.uuid!)
|
case '1GT':
|
||||||
.toList(),
|
return OneGangGlassSwitchBatchControlView(
|
||||||
|
deviceIds: devices.where((e) => (e.productType == '1GT')).map((e) => e.uuid!).toList(),
|
||||||
|
);
|
||||||
|
case '2GT':
|
||||||
|
return TwoGangGlassSwitchBatchControlView(
|
||||||
|
deviceIds: devices.where((e) => (e.productType == '2GT')).map((e) => e.uuid!).toList(),
|
||||||
);
|
);
|
||||||
case 'GW':
|
case 'GW':
|
||||||
return GatewayBatchControlView(
|
return GatewayBatchControlView(
|
||||||
gatewayIds: devices
|
gatewayIds: devices.where((e) => (e.productType == 'GW')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'GW'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case 'DL':
|
case 'DL':
|
||||||
return DoorLockBatchControlView(
|
return DoorLockBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'DL')).map((e) => e.uuid!).toList());
|
||||||
.where((e) => (e.productType == 'DL'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList());
|
|
||||||
case 'WPS':
|
case 'WPS':
|
||||||
return WallSensorBatchControlView(
|
return WallSensorBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'WPS')).map((e) => e.uuid!).toList());
|
||||||
.where((e) => (e.productType == 'WPS'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList());
|
|
||||||
case 'CPS':
|
case 'CPS':
|
||||||
return CeilingSensorBatchControlView(
|
return CeilingSensorBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'CPS')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'CPS'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case 'CUR':
|
case 'CUR':
|
||||||
return CurtainBatchStatusView(
|
return CurtainBatchStatusView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'CUR')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'CUR'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case 'AC':
|
case 'AC':
|
||||||
return AcDeviceBatchControlView(
|
return AcDeviceBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'AC')).map((e) => e.uuid!).toList());
|
||||||
.where((e) => (e.productType == 'AC'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList());
|
|
||||||
case 'WH':
|
case 'WH':
|
||||||
return WaterHEaterBatchControlView(
|
return WaterHEaterBatchControlView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == 'WH')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'WH'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case 'DS':
|
case 'DS':
|
||||||
return MainDoorSensorBatchView(
|
return MainDoorSensorBatchView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'DS')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'DS'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
|
part 'one_gang_glass_switch_event.dart';
|
||||||
|
part 'one_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
|
||||||
|
OneGangGlassStatusModel deviceStatus;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBloc({required String deviceId})
|
||||||
|
: deviceStatus = OneGangGlassStatusModel(uuid: deviceId, switch1: false, countDown: 0),
|
||||||
|
super(OneGangGlassSwitchInitial()) {
|
||||||
|
on<OneGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
||||||
|
on<OneGangGlassSwitchControl>(_onControl);
|
||||||
|
on<OneGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
|
on<OneGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchDeviceStatus(
|
||||||
|
OneGangGlassSwitchFetchDeviceEvent event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
emit(OneGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(OneGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onControl(OneGangGlassSwitchControl event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceId,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(OneGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceIds,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchBatchStatus(
|
||||||
|
OneGangGlassSwitchFetchBatchStatusEvent event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
emit(OneGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
||||||
|
emit(OneGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(OneGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _runDebounce({
|
||||||
|
required dynamic deviceId,
|
||||||
|
required String code,
|
||||||
|
required bool value,
|
||||||
|
required bool oldValue,
|
||||||
|
required Emitter<OneGangGlassSwitchState> emit,
|
||||||
|
required bool isBatch,
|
||||||
|
}) async {
|
||||||
|
late String id;
|
||||||
|
if (deviceId is List) {
|
||||||
|
id = deviceId.first;
|
||||||
|
} else {
|
||||||
|
id = deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_timer != null) {
|
||||||
|
_timer!.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
|
try {
|
||||||
|
late bool response;
|
||||||
|
if (isBatch) {
|
||||||
|
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
||||||
|
} else {
|
||||||
|
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<OneGangGlassSwitchState> emit) {
|
||||||
|
_updateLocalValue(code, oldValue);
|
||||||
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateLocalValue(String code, bool value) {
|
||||||
|
if (code == 'switch_1') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch1: value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _getValueByCode(String code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'switch_1':
|
||||||
|
return deviceStatus.switch1;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
_timer?.cancel();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
part of 'one_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class OneGangGlassSwitchEvent {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchFetchDeviceEvent extends OneGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
OneGangGlassSwitchFetchDeviceEvent(this.deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchControl extends OneGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
OneGangGlassSwitchControl({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchControl extends OneGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBatchControl({
|
||||||
|
required this.deviceIds,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchFetchBatchStatusEvent extends OneGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
OneGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
part of 'one_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class OneGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchInitial extends OneGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchLoading extends OneGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchStatusLoaded extends OneGangGlassSwitchState {
|
||||||
|
final OneGangGlassStatusModel status;
|
||||||
|
|
||||||
|
OneGangGlassSwitchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchError extends OneGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
OneGangGlassSwitchError(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchStatusLoaded extends OneGangGlassSwitchState {
|
||||||
|
final OneGangGlassStatusModel status;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBatchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchControlError extends OneGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBatchControlError(this.message);
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
|
||||||
|
class OneGangGlassStatusModel {
|
||||||
|
final String uuid;
|
||||||
|
final bool switch1;
|
||||||
|
final int countDown;
|
||||||
|
|
||||||
|
OneGangGlassStatusModel({
|
||||||
|
required this.uuid,
|
||||||
|
required this.switch1,
|
||||||
|
required this.countDown,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory OneGangGlassStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||||
|
late bool switch1;
|
||||||
|
late int countDown;
|
||||||
|
|
||||||
|
for (var status in jsonList) {
|
||||||
|
switch (status.code) {
|
||||||
|
case 'switch_1':
|
||||||
|
switch1 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_1':
|
||||||
|
countDown = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OneGangGlassStatusModel(
|
||||||
|
uuid: id,
|
||||||
|
switch1: switch1,
|
||||||
|
countDown: countDown,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
OneGangGlassStatusModel copyWith({
|
||||||
|
String? uuid,
|
||||||
|
bool? switch1,
|
||||||
|
int? countDown,
|
||||||
|
}) {
|
||||||
|
return OneGangGlassStatusModel(
|
||||||
|
uuid: uuid ?? this.uuid,
|
||||||
|
switch1: switch1 ?? this.switch1,
|
||||||
|
countDown: countDown ?? this.countDown,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'OneGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown: $countDown)';
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
const OneGangGlassSwitchBatchControlView({required this.deviceIds, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
OneGangGlassSwitchBloc(deviceId: deviceIds.first)..add(OneGangGlassSwitchFetchBatchStatusEvent(deviceIds)),
|
||||||
|
child: BlocBuilder<OneGangGlassSwitchBloc, OneGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is OneGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is OneGangGlassSwitchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is OneGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Wall Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<OneGangGlassSwitchBloc>().add(
|
||||||
|
OneGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FirmwareUpdateWidget(
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
version: 12, // adjust the version according to your requirement
|
||||||
|
),
|
||||||
|
FactoryResetWidget(
|
||||||
|
callFactoryReset: () {},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
const OneGangGlassSwitchControlView({required this.deviceId, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
OneGangGlassSwitchBloc(deviceId: deviceId)..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)),
|
||||||
|
child: BlocBuilder<OneGangGlassSwitchBloc, OneGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is OneGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is OneGangGlassSwitchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is OneGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Wall Lightً',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<OneGangGlassSwitchBloc>().add(
|
||||||
|
OneGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
|
part 'two_gang_glass_switch_event.dart';
|
||||||
|
part 'two_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBloc extends Bloc<TwoGangGlassSwitchEvent, TwoGangGlassSwitchState> {
|
||||||
|
TwoGangGlassStatusModel deviceStatus;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBloc({required String deviceId})
|
||||||
|
: deviceStatus =
|
||||||
|
TwoGangGlassStatusModel(uuid: deviceId, switch1: false, countDown1: 0, switch2: false, countDown2: 0),
|
||||||
|
super(TwoGangGlassSwitchInitial()) {
|
||||||
|
on<TwoGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
||||||
|
on<TwoGangGlassSwitchControl>(_onControl);
|
||||||
|
on<TwoGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
|
on<TwoGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
|
on<TwoGangGlassFactoryReset>(_onFactoryReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchDeviceStatus(
|
||||||
|
TwoGangGlassSwitchFetchDeviceEvent event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
emit(TwoGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(TwoGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onControl(TwoGangGlassSwitchControl event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceId,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onBatchControl(TwoGangGlassSwitchBatchControl event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceIds,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchBatchStatus(
|
||||||
|
TwoGangGlassSwitchFetchBatchStatusEvent event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
emit(TwoGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
||||||
|
emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(TwoGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFactoryReset(TwoGangGlassFactoryReset event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
emit(TwoGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
||||||
|
if (!response) {
|
||||||
|
emit(TwoGangGlassSwitchError('Failed'));
|
||||||
|
} else {
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(TwoGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _runDebounce({
|
||||||
|
required dynamic deviceId,
|
||||||
|
required String code,
|
||||||
|
required bool value,
|
||||||
|
required bool oldValue,
|
||||||
|
required Emitter<TwoGangGlassSwitchState> emit,
|
||||||
|
required bool isBatch,
|
||||||
|
}) async {
|
||||||
|
late String id;
|
||||||
|
if (deviceId is List) {
|
||||||
|
id = deviceId.first;
|
||||||
|
} else {
|
||||||
|
id = deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_timer != null) {
|
||||||
|
_timer!.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
|
try {
|
||||||
|
late bool response;
|
||||||
|
if (isBatch) {
|
||||||
|
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
||||||
|
} else {
|
||||||
|
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<TwoGangGlassSwitchState> emit) {
|
||||||
|
_updateLocalValue(code, oldValue);
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateLocalValue(String code, bool value) {
|
||||||
|
if (code == 'switch_1') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch1: value);
|
||||||
|
} else if (code == 'switch_2') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch2: value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _getValueByCode(String code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'switch_1':
|
||||||
|
return deviceStatus.switch1;
|
||||||
|
case 'switch_2':
|
||||||
|
return deviceStatus.switch2;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
_timer?.cancel();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
part of 'two_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class TwoGangGlassSwitchEvent {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchFetchDeviceEvent extends TwoGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchFetchDeviceEvent(this.deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchControl extends TwoGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchControl({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchControl extends TwoGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBatchControl({
|
||||||
|
required this.deviceIds,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchFetchBatchStatusEvent extends TwoGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassFactoryReset extends TwoGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final FactoryResetModel factoryReset;
|
||||||
|
|
||||||
|
TwoGangGlassFactoryReset({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.factoryReset,
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
part of 'two_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class TwoGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchInitial extends TwoGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchLoading extends TwoGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchStatusLoaded extends TwoGangGlassSwitchState {
|
||||||
|
final TwoGangGlassStatusModel status;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchError extends TwoGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchError(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchStatusLoaded extends TwoGangGlassSwitchState {
|
||||||
|
final TwoGangGlassStatusModel status;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBatchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchControlError extends TwoGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBatchControlError(this.message);
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassStatusModel {
|
||||||
|
final String uuid;
|
||||||
|
final bool switch1;
|
||||||
|
final int countDown1;
|
||||||
|
final bool switch2;
|
||||||
|
final int countDown2;
|
||||||
|
|
||||||
|
TwoGangGlassStatusModel({
|
||||||
|
required this.uuid,
|
||||||
|
required this.switch1,
|
||||||
|
required this.countDown1,
|
||||||
|
required this.switch2,
|
||||||
|
required this.countDown2,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TwoGangGlassStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||||
|
late bool switch1;
|
||||||
|
late int countDown1;
|
||||||
|
late bool switch2;
|
||||||
|
late int countDown2;
|
||||||
|
|
||||||
|
for (var status in jsonList) {
|
||||||
|
switch (status.code) {
|
||||||
|
case 'switch_1':
|
||||||
|
switch1 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_1':
|
||||||
|
countDown1 = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
case 'switch_2':
|
||||||
|
switch2 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_2':
|
||||||
|
countDown2 = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TwoGangGlassStatusModel(
|
||||||
|
uuid: id,
|
||||||
|
switch1: switch1,
|
||||||
|
countDown1: countDown1,
|
||||||
|
switch2: switch2,
|
||||||
|
countDown2: countDown2,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoGangGlassStatusModel copyWith({
|
||||||
|
String? uuid,
|
||||||
|
bool? switch1,
|
||||||
|
int? countDown1,
|
||||||
|
bool? switch2,
|
||||||
|
int? countDown2,
|
||||||
|
}) {
|
||||||
|
return TwoGangGlassStatusModel(
|
||||||
|
uuid: uuid ?? this.uuid,
|
||||||
|
switch1: switch1 ?? this.switch1,
|
||||||
|
countDown1: countDown1 ?? this.countDown1,
|
||||||
|
switch2: switch2 ?? this.switch2,
|
||||||
|
countDown2: countDown2 ?? this.countDown2,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'TwoGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown1: $countDown1, switch2: $switch2, countDown2: $countDown2)';
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
const TwoGangGlassSwitchBatchControlView({required this.deviceIds, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
TwoGangGlassSwitchBloc(deviceId: deviceIds.first)..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)),
|
||||||
|
child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is TwoGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is TwoGangGlassSwitchBatchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is TwoGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Wall Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch2,
|
||||||
|
code: 'switch_2',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Ceiling Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FirmwareUpdateWidget(
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
version: 12, // adjust the version according to your requirement
|
||||||
|
),
|
||||||
|
FactoryResetWidget(
|
||||||
|
callFactoryReset: () {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassFactoryReset(
|
||||||
|
deviceId: status.uuid,
|
||||||
|
factoryReset: FactoryResetModel(devicesUuid: deviceIds),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
const TwoGangGlassSwitchControlView({required this.deviceId, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
TwoGangGlassSwitchBloc(deviceId: deviceId)..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)),
|
||||||
|
child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is TwoGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is TwoGangGlassSwitchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is TwoGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Wall Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch2,
|
||||||
|
code: 'switch_2',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Ceiling Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user