mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
20
assets/icons/preferences.svg
Normal file
20
assets/icons/preferences.svg
Normal file
@ -0,0 +1,20 @@
|
||||
<svg width="36" height="33" viewBox="0 0 36 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M32.7404 13.0391H30.5674V19.5582H32.7404C34.5406 19.5582 36 18.0988 36 16.2986C36 14.4984 34.5406 13.0391 32.7404 13.0391Z" fill="#A5A8AB"/>
|
||||
<path d="M30.5674 13.0391H3.25956C1.45934 13.0391 0 14.4984 0 16.2986C0 18.0988 1.45934 19.5582 3.25956 19.5582H30.5674C32.3676 19.5582 33.827 18.0988 33.827 16.2986C33.827 14.4984 32.3676 13.0391 30.5674 13.0391Z" fill="#C2C4C6"/>
|
||||
<path d="M32.7404 15.2119H30.5674V17.385H32.7404C33.3405 17.385 33.8269 16.8985 33.8269 16.2984C33.8269 15.6984 33.3405 15.2119 32.7404 15.2119Z" fill="#414851"/>
|
||||
<path d="M30.5672 15.2119H3.25937C2.65932 15.2119 2.17285 15.6984 2.17285 16.2984C2.17285 16.8985 2.65932 17.385 3.25937 17.385H30.5672C31.1673 17.385 31.6537 16.8985 31.6537 16.2984C31.6537 15.6984 31.1673 15.2119 30.5672 15.2119Z" fill="#62676F"/>
|
||||
<path d="M11.9521 10.8652V21.7304C14.9525 21.7304 17.3847 19.2981 17.3847 16.2978C17.3847 13.2975 14.9525 10.8652 11.9521 10.8652Z" fill="#FCBE64"/>
|
||||
<path d="M15.2117 16.2978C15.2117 13.2975 13.7523 10.8652 11.9521 10.8652C8.95181 10.8652 6.51953 13.2975 6.51953 16.2978C6.51953 19.2981 8.95181 21.7304 11.9521 21.7304C13.7523 21.7304 15.2117 19.2981 15.2117 16.2978Z" fill="#FBDB63"/>
|
||||
<path d="M32.7404 2.17285H30.5674V8.69197H32.7404C34.5406 8.69197 36 7.23263 36 5.43241C36 3.63219 34.5406 2.17285 32.7404 2.17285Z" fill="#A5A8AB"/>
|
||||
<path d="M30.5674 2.17285H3.25956C1.45934 2.17285 0 3.63219 0 5.43241C0 7.23263 1.45934 8.69197 3.25956 8.69197H30.5674C32.3676 8.69197 33.827 7.23263 33.827 5.43241C33.827 3.63219 32.3676 2.17285 30.5674 2.17285Z" fill="#C2C4C6"/>
|
||||
<path d="M32.7404 4.3457H30.5674V6.51874H32.7404C33.3405 6.51874 33.8269 6.03227 33.8269 5.43222C33.8269 4.83217 33.3405 4.3457 32.7404 4.3457Z" fill="#414851"/>
|
||||
<path d="M30.5672 4.3457H3.25937C2.65932 4.3457 2.17285 4.83217 2.17285 5.43222C2.17285 6.03227 2.65932 6.51874 3.25937 6.51874H30.5672C31.1673 6.51874 31.6537 6.03227 31.6537 5.43222C31.6537 4.83217 31.1673 4.3457 30.5672 4.3457Z" fill="#62676F"/>
|
||||
<path d="M24.0479 0V10.8652C27.0482 10.8652 29.4804 8.43291 29.4804 5.4326C29.4804 2.43228 27.0482 0 24.0479 0Z" fill="#FA342D"/>
|
||||
<path d="M27.3074 5.4326C27.3074 2.43228 25.848 0 24.0478 0C21.0475 0 18.6152 2.43228 18.6152 5.4326C18.6152 8.43291 21.0475 10.8652 24.0478 10.8652C25.848 10.8652 27.3074 8.43291 27.3074 5.4326Z" fill="#FE5E49"/>
|
||||
<path d="M32.7404 23.9033H30.5674V30.4224H32.7404C34.5406 30.4224 36 28.9631 36 27.1629C36 25.3627 34.5406 23.9033 32.7404 23.9033Z" fill="#A5A8AB"/>
|
||||
<path d="M30.5674 23.9033H3.25956C1.45934 23.9033 0 25.3627 0 27.1629C0 28.9631 1.45934 30.4224 3.25956 30.4224H30.5674C32.3676 30.4224 33.827 28.9631 33.827 27.1629C33.827 25.3627 32.3676 23.9033 30.5674 23.9033Z" fill="#C2C4C6"/>
|
||||
<path d="M32.7404 26.0762H30.5674V28.2492H32.7404C33.3405 28.2492 33.8269 27.7627 33.8269 27.1627C33.8269 26.5626 33.3405 26.0762 32.7404 26.0762Z" fill="#414851"/>
|
||||
<path d="M30.5672 26.0762H3.25937C2.65932 26.0762 2.17285 26.5626 2.17285 27.1627C2.17285 27.7627 2.65932 28.2492 3.25937 28.2492H30.5672C31.1673 28.2492 31.6537 27.7627 31.6537 27.1627C31.6537 26.5626 31.1673 26.0762 30.5672 26.0762Z" fill="#62676F"/>
|
||||
<path d="M24.0479 21.7295V32.5947C27.0482 32.5947 29.4804 30.1624 29.4804 27.1621C29.4804 24.1618 27.0482 21.7295 24.0479 21.7295Z" fill="#7D99E8"/>
|
||||
<path d="M27.3074 27.1621C27.3074 24.1618 25.848 21.7295 24.0478 21.7295C21.0475 21.7295 18.6152 24.1618 18.6152 27.1621C18.6152 30.1624 21.0475 32.5947 24.0478 32.5947C25.848 32.5947 27.3074 30.1624 27.3074 27.1621Z" fill="#83B3F1"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
@ -2,11 +2,11 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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/home/bloc/home_bloc.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:go_router/go_router.dart';
|
||||
import 'package:syncrow_web/services/locator.dart';
|
||||
import 'package:syncrow_web/utils/app_routes.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 {
|
||||
try {
|
||||
const environment =
|
||||
String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
||||
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
||||
await dotenv.load(fileName: '.env.$environment');
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
initialSetup();
|
||||
@ -45,11 +44,9 @@ class MyApp extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//HomeBloc.fetchUserInfo();
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||
BlocProvider<VisitorPasswordBloc>(
|
||||
create: (context) => VisitorPasswordBloc(),
|
||||
)
|
||||
|
@ -13,10 +13,15 @@ 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/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/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_device_control.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.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/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_device_control.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart';
|
||||
@ -24,6 +29,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_device_control.dart';
|
||||
|
||||
import '../../one_g_glass_switch/view/one_gang_glass_switch_control_view.dart';
|
||||
|
||||
mixin RouteControlsBasedCode {
|
||||
Widget routeControlsWidgets({required AllDevicesModel device}) {
|
||||
switch (device.productType) {
|
||||
@ -39,6 +46,18 @@ mixin RouteControlsBasedCode {
|
||||
return LivingRoomDeviceControlsView(
|
||||
deviceId: device.uuid!,
|
||||
);
|
||||
case '1GT':
|
||||
return OneGangGlassSwitchControlView(
|
||||
deviceId: device.uuid!,
|
||||
);
|
||||
case '2GT':
|
||||
return TwoGangGlassSwitchControlView(
|
||||
deviceId: device.uuid!,
|
||||
);
|
||||
case '3GT':
|
||||
return ThreeGangGlassSwitchControlView(
|
||||
deviceId: device.uuid!,
|
||||
);
|
||||
case 'GW':
|
||||
return GateWayControlsView(
|
||||
gatewayId: device.uuid!,
|
||||
@ -86,77 +105,56 @@ mixin RouteControlsBasedCode {
|
||||
switch (devices.first.productType) {
|
||||
case '1G':
|
||||
return WallLightBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '1G'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '1G')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '2G':
|
||||
return TwoGangBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '2G'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '2G')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '3G':
|
||||
return LivingRoomBatchControlsView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == '3G'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == '3G')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case '1GT':
|
||||
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 '3GT':
|
||||
return ThreeGangGlassSwitchBatchControlView(
|
||||
deviceIds: devices.where((e) => (e.productType == '3GT')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'GW':
|
||||
return GatewayBatchControlView(
|
||||
gatewayIds: devices
|
||||
.where((e) => (e.productType == 'GW'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
gatewayIds: devices.where((e) => (e.productType == 'GW')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'DL':
|
||||
return DoorLockBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'DL'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList());
|
||||
devicesIds: devices.where((e) => (e.productType == 'DL')).map((e) => e.uuid!).toList());
|
||||
case 'WPS':
|
||||
return WallSensorBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'WPS'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList());
|
||||
devicesIds: devices.where((e) => (e.productType == 'WPS')).map((e) => e.uuid!).toList());
|
||||
case 'CPS':
|
||||
return CeilingSensorBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'CPS'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
devicesIds: devices.where((e) => (e.productType == 'CPS')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'CUR':
|
||||
return CurtainBatchStatusView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'CUR'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
devicesIds: devices.where((e) => (e.productType == 'CUR')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'AC':
|
||||
return AcDeviceBatchControlView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'AC'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList());
|
||||
devicesIds: devices.where((e) => (e.productType == 'AC')).map((e) => e.uuid!).toList());
|
||||
case 'WH':
|
||||
return WaterHEaterBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == 'WH'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
deviceIds: devices.where((e) => (e.productType == 'WH')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
case 'DS':
|
||||
return MainDoorSensorBatchView(
|
||||
devicesIds: devices
|
||||
.where((e) => (e.productType == 'DS'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
devicesIds: devices.where((e) => (e.productType == 'DS')).map((e) => e.uuid!).toList(),
|
||||
);
|
||||
default:
|
||||
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,90 @@
|
||||
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/constants/assets.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,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: false,
|
||||
code: '',
|
||||
deviceId: deviceId,
|
||||
label: 'Preferences',
|
||||
icon: Assets.preferences,
|
||||
onChange: (value) {},
|
||||
showToggle: false,
|
||||
),
|
||||
ToggleWidget(
|
||||
value: false,
|
||||
code: '',
|
||||
deviceId: deviceId,
|
||||
label: 'Scheduling',
|
||||
icon: Assets.scheduling,
|
||||
onChange: (value) {},
|
||||
showToggle: false,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
@ -13,6 +12,7 @@ class ToggleWidget extends StatelessWidget {
|
||||
final String? icon;
|
||||
final Widget? labelWidget;
|
||||
final Function(dynamic value) onChange;
|
||||
final bool showToggle;
|
||||
|
||||
const ToggleWidget({
|
||||
super.key,
|
||||
@ -23,6 +23,7 @@ class ToggleWidget extends StatelessWidget {
|
||||
required this.onChange,
|
||||
this.icon,
|
||||
this.labelWidget,
|
||||
this.showToggle = true,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -62,6 +63,7 @@ class ToggleWidget extends StatelessWidget {
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)),
|
||||
if (showToggle)
|
||||
Container(
|
||||
height: 20,
|
||||
width: 35,
|
||||
|
@ -0,0 +1,174 @@
|
||||
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/three_g_glass_switch/models/three_gang_glass_switch.dart';
|
||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||
|
||||
part 'three_gang_glass_switch_event.dart';
|
||||
part 'three_gang_glass_switch_state.dart';
|
||||
|
||||
class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGangGlassSwitchState> {
|
||||
ThreeGangGlassStatusModel deviceStatus;
|
||||
Timer? _timer;
|
||||
|
||||
ThreeGangGlassSwitchBloc({required String deviceId})
|
||||
: deviceStatus = ThreeGangGlassStatusModel(
|
||||
uuid: deviceId,
|
||||
switch1: false,
|
||||
countDown1: 0,
|
||||
switch2: false,
|
||||
countDown2: 0,
|
||||
switch3: false,
|
||||
countDown3: 0),
|
||||
super(ThreeGangGlassSwitchInitial()) {
|
||||
on<ThreeGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
||||
on<ThreeGangGlassSwitchControl>(_onControl);
|
||||
on<ThreeGangGlassSwitchBatchControl>(_onBatchControl);
|
||||
on<ThreeGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||
on<ThreeGangGlassFactoryReset>(_onFactoryReset);
|
||||
}
|
||||
|
||||
Future<void> _onFetchDeviceStatus(
|
||||
ThreeGangGlassSwitchFetchDeviceEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||
emit(ThreeGangGlassSwitchLoading());
|
||||
try {
|
||||
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||
deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||
} catch (e) {
|
||||
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onControl(ThreeGangGlassSwitchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||
final oldValue = _getValueByCode(event.code);
|
||||
|
||||
_updateLocalValue(event.code, event.value);
|
||||
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||
|
||||
await _runDebounce(
|
||||
deviceId: event.deviceId,
|
||||
code: event.code,
|
||||
value: event.value,
|
||||
oldValue: oldValue,
|
||||
emit: emit,
|
||||
isBatch: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onBatchControl(ThreeGangGlassSwitchBatchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||
final oldValue = _getValueByCode(event.code);
|
||||
|
||||
_updateLocalValue(event.code, event.value);
|
||||
emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||
|
||||
await _runDebounce(
|
||||
deviceId: event.deviceIds,
|
||||
code: event.code,
|
||||
value: event.value,
|
||||
oldValue: oldValue,
|
||||
emit: emit,
|
||||
isBatch: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onFetchBatchStatus(
|
||||
ThreeGangGlassSwitchFetchBatchStatusEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||
emit(ThreeGangGlassSwitchLoading());
|
||||
try {
|
||||
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||
deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
||||
emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||
} catch (e) {
|
||||
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onFactoryReset(ThreeGangGlassFactoryReset event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||
emit(ThreeGangGlassSwitchLoading());
|
||||
try {
|
||||
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
||||
if (!response) {
|
||||
emit(ThreeGangGlassSwitchError('Failed'));
|
||||
} else {
|
||||
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _runDebounce({
|
||||
required dynamic deviceId,
|
||||
required String code,
|
||||
required bool value,
|
||||
required bool oldValue,
|
||||
required Emitter<ThreeGangGlassSwitchState> 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<ThreeGangGlassSwitchState> emit) {
|
||||
_updateLocalValue(code, oldValue);
|
||||
emit(ThreeGangGlassSwitchStatusLoaded(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);
|
||||
} else if (code == 'switch_3') {
|
||||
deviceStatus = deviceStatus.copyWith(switch3: value);
|
||||
}
|
||||
}
|
||||
|
||||
bool _getValueByCode(String code) {
|
||||
switch (code) {
|
||||
case 'switch_1':
|
||||
return deviceStatus.switch1;
|
||||
case 'switch_2':
|
||||
return deviceStatus.switch2;
|
||||
case 'switch_3':
|
||||
return deviceStatus.switch3;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_timer?.cancel();
|
||||
return super.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
part of 'three_gang_glass_switch_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ThreeGangGlassSwitchEvent {}
|
||||
|
||||
class ThreeGangGlassSwitchFetchDeviceEvent extends ThreeGangGlassSwitchEvent {
|
||||
final String deviceId;
|
||||
|
||||
ThreeGangGlassSwitchFetchDeviceEvent(this.deviceId);
|
||||
}
|
||||
|
||||
class ThreeGangGlassSwitchControl extends ThreeGangGlassSwitchEvent {
|
||||
final String deviceId;
|
||||
final String code;
|
||||
final bool value;
|
||||
|
||||
ThreeGangGlassSwitchControl({
|
||||
required this.deviceId,
|
||||
required this.code,
|
||||
required this.value,
|
||||
});
|
||||
}
|
||||
|
||||
class ThreeGangGlassSwitchBatchControl extends ThreeGangGlassSwitchEvent {
|
||||
final List<String> deviceIds;
|
||||
final String code;
|
||||
final bool value;
|
||||
|
||||
ThreeGangGlassSwitchBatchControl({
|
||||
required this.deviceIds,
|
||||
required this.code,
|
||||
required this.value,
|
||||
});
|
||||
}
|
||||
|
||||
class ThreeGangGlassSwitchFetchBatchStatusEvent extends ThreeGangGlassSwitchEvent {
|
||||
final List<String> deviceIds;
|
||||
|
||||
ThreeGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
||||
}
|
||||
|
||||
class ThreeGangGlassFactoryReset extends ThreeGangGlassSwitchEvent {
|
||||
final String deviceId;
|
||||
final FactoryResetModel factoryReset;
|
||||
|
||||
ThreeGangGlassFactoryReset({
|
||||
required this.deviceId,
|
||||
required this.factoryReset,
|
||||
});
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
part of 'three_gang_glass_switch_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ThreeGangGlassSwitchState {}
|
||||
|
||||
class ThreeGangGlassSwitchInitial extends ThreeGangGlassSwitchState {}
|
||||
|
||||
class ThreeGangGlassSwitchLoading extends ThreeGangGlassSwitchState {}
|
||||
|
||||
class ThreeGangGlassSwitchStatusLoaded extends ThreeGangGlassSwitchState {
|
||||
final ThreeGangGlassStatusModel status;
|
||||
|
||||
ThreeGangGlassSwitchStatusLoaded(this.status);
|
||||
}
|
||||
|
||||
class ThreeGangGlassSwitchError extends ThreeGangGlassSwitchState {
|
||||
final String message;
|
||||
|
||||
ThreeGangGlassSwitchError(this.message);
|
||||
}
|
||||
|
||||
class ThreeGangGlassSwitchBatchStatusLoaded extends ThreeGangGlassSwitchState {
|
||||
final ThreeGangGlassStatusModel status;
|
||||
|
||||
ThreeGangGlassSwitchBatchStatusLoaded(this.status);
|
||||
}
|
||||
|
||||
class ThreeGangGlassSwitchBatchControlError extends ThreeGangGlassSwitchState {
|
||||
final String message;
|
||||
|
||||
ThreeGangGlassSwitchBatchControlError(this.message);
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
|
||||
class ThreeGangGlassStatusModel {
|
||||
final String uuid;
|
||||
final bool switch1;
|
||||
final int countDown1;
|
||||
final bool switch2;
|
||||
final int countDown2;
|
||||
final bool switch3;
|
||||
final int countDown3;
|
||||
|
||||
ThreeGangGlassStatusModel({
|
||||
required this.uuid,
|
||||
required this.switch1,
|
||||
required this.countDown1,
|
||||
required this.switch2,
|
||||
required this.countDown2,
|
||||
required this.switch3,
|
||||
required this.countDown3,
|
||||
});
|
||||
|
||||
factory ThreeGangGlassStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||
late bool switch1;
|
||||
late int countDown1;
|
||||
late bool switch2;
|
||||
late int countDown2;
|
||||
late bool switch3;
|
||||
late int countDown3;
|
||||
|
||||
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;
|
||||
case 'switch_3':
|
||||
switch3 = status.value ?? false;
|
||||
break;
|
||||
case 'countdown_3':
|
||||
countDown3 = status.value ?? 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ThreeGangGlassStatusModel(
|
||||
uuid: id,
|
||||
switch1: switch1,
|
||||
countDown1: countDown1,
|
||||
switch2: switch2,
|
||||
countDown2: countDown2,
|
||||
switch3: switch3,
|
||||
countDown3: countDown3,
|
||||
);
|
||||
}
|
||||
|
||||
ThreeGangGlassStatusModel copyWith({
|
||||
String? uuid,
|
||||
bool? switch1,
|
||||
int? countDown1,
|
||||
bool? switch2,
|
||||
int? countDown2,
|
||||
bool? switch3,
|
||||
int? countDown3,
|
||||
}) {
|
||||
return ThreeGangGlassStatusModel(
|
||||
uuid: uuid ?? this.uuid,
|
||||
switch1: switch1 ?? this.switch1,
|
||||
countDown1: countDown1 ?? this.countDown1,
|
||||
switch2: switch2 ?? this.switch2,
|
||||
countDown2: countDown2 ?? this.countDown2,
|
||||
switch3: switch3 ?? this.switch3,
|
||||
countDown3: countDown3 ?? this.countDown3,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'ThreeGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown1: $countDown1, switch2: $switch2, countDown2: $countDown2, switch3: $switch3, countDown3: $countDown3)';
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
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/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||
final List<String> deviceIds;
|
||||
|
||||
const ThreeGangGlassSwitchBatchControlView({required this.deviceIds, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => ThreeGangGlassSwitchBloc(deviceId: deviceIds.first)
|
||||
..add(ThreeGangGlassSwitchFetchBatchStatusEvent(deviceIds)),
|
||||
child: BlocBuilder<ThreeGangGlassSwitchBloc, ThreeGangGlassSwitchState>(
|
||||
builder: (context, state) {
|
||||
if (state is ThreeGangGlassSwitchLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is ThreeGangGlassSwitchBatchStatusLoaded) {
|
||||
return _buildStatusControls(context, state.status);
|
||||
} else if (state is ThreeGangGlassSwitchError) {
|
||||
return const Center(child: Text('Error fetching status'));
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel 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: 'Glass Switch 1',
|
||||
onChange: (value) {
|
||||
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||
ThreeGangGlassSwitchBatchControl(
|
||||
deviceIds: deviceIds,
|
||||
code: 'switch_1',
|
||||
value: value,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: status.switch2,
|
||||
code: 'switch_2',
|
||||
deviceId: deviceIds.first,
|
||||
label: 'Glass Switch 2',
|
||||
onChange: (value) {
|
||||
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||
ThreeGangGlassSwitchBatchControl(
|
||||
deviceIds: deviceIds,
|
||||
code: 'switch_2',
|
||||
value: value,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: status.switch3,
|
||||
code: 'switch_3',
|
||||
deviceId: deviceIds.first,
|
||||
label: 'Glass Switch 3',
|
||||
onChange: (value) {
|
||||
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||
ThreeGangGlassSwitchBatchControl(
|
||||
deviceIds: deviceIds,
|
||||
code: 'switch_3',
|
||||
value: value,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
FirmwareUpdateWidget(
|
||||
deviceId: deviceIds.first,
|
||||
version: 12, // adjust the version according to your requirement
|
||||
),
|
||||
FactoryResetWidget(
|
||||
callFactoryReset: () {
|
||||
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||
ThreeGangGlassFactoryReset(
|
||||
deviceId: status.uuid,
|
||||
factoryReset: FactoryResetModel(devicesUuid: deviceIds),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
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/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
import '../models/three_gang_glass_switch.dart';
|
||||
|
||||
class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||
final String deviceId;
|
||||
|
||||
const ThreeGangGlassSwitchControlView({required this.deviceId, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
ThreeGangGlassSwitchBloc(deviceId: deviceId)..add(ThreeGangGlassSwitchFetchDeviceEvent(deviceId)),
|
||||
child: BlocBuilder<ThreeGangGlassSwitchBloc, ThreeGangGlassSwitchState>(
|
||||
builder: (context, state) {
|
||||
if (state is ThreeGangGlassSwitchLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is ThreeGangGlassSwitchStatusLoaded) {
|
||||
return _buildStatusControls(context, state.status);
|
||||
} else if (state is ThreeGangGlassSwitchError) {
|
||||
return const Center(child: Text('Error fetching status'));
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel 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<ThreeGangGlassSwitchBloc>().add(
|
||||
ThreeGangGlassSwitchControl(
|
||||
deviceId: deviceId,
|
||||
code: 'switch_1',
|
||||
value: value,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: status.switch2,
|
||||
code: 'switch_2',
|
||||
deviceId: deviceId,
|
||||
label: 'Ceiling Light',
|
||||
onChange: (value) {
|
||||
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||
ThreeGangGlassSwitchControl(
|
||||
deviceId: deviceId,
|
||||
code: 'switch_2',
|
||||
value: value,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: status.switch3,
|
||||
code: 'switch_3',
|
||||
deviceId: deviceId,
|
||||
label: 'SpotLight',
|
||||
onChange: (value) {
|
||||
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||
ThreeGangGlassSwitchControl(
|
||||
deviceId: deviceId,
|
||||
code: 'switch_3',
|
||||
value: value,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: false,
|
||||
code: '',
|
||||
deviceId: deviceId,
|
||||
label: 'Preferences',
|
||||
icon: Assets.preferences,
|
||||
onChange: (value) {},
|
||||
showToggle: false,
|
||||
),
|
||||
ToggleWidget(
|
||||
value: false,
|
||||
code: '',
|
||||
deviceId: deviceId,
|
||||
label: 'Scheduling',
|
||||
icon: Assets.scheduling,
|
||||
onChange: (value) {},
|
||||
showToggle: false,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -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,105 @@
|
||||
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/constants/assets.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,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: false,
|
||||
code: '',
|
||||
deviceId: deviceId,
|
||||
label: 'Preferences',
|
||||
icon: Assets.preferences,
|
||||
onChange: (value) {},
|
||||
showToggle: false,
|
||||
),
|
||||
ToggleWidget(
|
||||
value: false,
|
||||
code: '',
|
||||
deviceId: deviceId,
|
||||
label: 'Scheduling',
|
||||
icon: Assets.scheduling,
|
||||
onChange: (value) {},
|
||||
showToggle: false,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -13,12 +13,10 @@ class Assets {
|
||||
static const String rightLine = "assets/images/right_line.png";
|
||||
static const String google = "assets/images/google.svg";
|
||||
static const String facebook = "assets/images/facebook.svg";
|
||||
static const String invisiblePassword =
|
||||
"assets/images/Password_invisible.svg";
|
||||
static const String invisiblePassword = "assets/images/Password_invisible.svg";
|
||||
static const String visiblePassword = "assets/images/password_visible.svg";
|
||||
static const String accessIcon = "assets/images/access_icon.svg";
|
||||
static const String spaseManagementIcon =
|
||||
"assets/images/spase_management_icon.svg";
|
||||
static const String spaseManagementIcon = "assets/images/spase_management_icon.svg";
|
||||
static const String devicesIcon = "assets/images/devices_icon.svg";
|
||||
static const String moveinIcon = "assets/images/movein_icon.svg";
|
||||
static const String constructionIcon = "assets/images/construction_icon.svg";
|
||||
@ -31,15 +29,13 @@ class Assets {
|
||||
static const String emptyTable = "assets/images/empty_table.svg";
|
||||
|
||||
// General assets
|
||||
static const String motionlessDetection =
|
||||
"assets/icons/motionless_detection.svg";
|
||||
static const String motionlessDetection = "assets/icons/motionless_detection.svg";
|
||||
static const String acHeating = "assets/icons/ac_heating.svg";
|
||||
static const String acPowerOff = "assets/icons/ac_power_off.svg";
|
||||
static const String acFanMiddle = "assets/icons/ac_fan_middle.svg";
|
||||
static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg";
|
||||
static const String resetOff = "assets/icons/reset_off.svg";
|
||||
static const String sensitivityOperationIcon =
|
||||
"assets/icons/sesitivity_operation_icon.svg";
|
||||
static const String sensitivityOperationIcon = "assets/icons/sesitivity_operation_icon.svg";
|
||||
static const String motionDetection = "assets/icons/motion_detection.svg";
|
||||
static const String freezing = "assets/icons/freezing.svg";
|
||||
static const String indicator = "assets/icons/indicator.svg";
|
||||
@ -60,56 +56,35 @@ class Assets {
|
||||
static const String celsiusDegrees = "assets/icons/celsius_degrees.svg";
|
||||
static const String masterState = "assets/icons/master_state.svg";
|
||||
static const String acPower = "assets/icons/ac_power.svg";
|
||||
static const String farDetectionFunction =
|
||||
"assets/icons/far_detection_function.svg";
|
||||
static const String farDetectionFunction = "assets/icons/far_detection_function.svg";
|
||||
static const String nobodyTime = "assets/icons/nobody_time.svg";
|
||||
|
||||
// Automation functions
|
||||
static const String tempPasswordUnlock =
|
||||
"assets/icons/automation_functions/temp_password_unlock.svg";
|
||||
static const String doorlockNormalOpen =
|
||||
"assets/icons/automation_functions/doorlock_normal_open.svg";
|
||||
static const String doorbell =
|
||||
"assets/icons/automation_functions/doorbell.svg";
|
||||
static const String remoteUnlockViaApp =
|
||||
"assets/icons/automation_functions/remote_unlock_via_app.svg";
|
||||
static const String doubleLock =
|
||||
"assets/icons/automation_functions/double_lock.svg";
|
||||
static const String selfTestResult =
|
||||
"assets/icons/automation_functions/self_test_result.svg";
|
||||
static const String lockAlarm =
|
||||
"assets/icons/automation_functions/lock_alarm.svg";
|
||||
static const String presenceState =
|
||||
"assets/icons/automation_functions/presence_state.svg";
|
||||
static const String currentTemp =
|
||||
"assets/icons/automation_functions/current_temp.svg";
|
||||
static const String presence =
|
||||
"assets/icons/automation_functions/presence.svg";
|
||||
static const String residualElectricity =
|
||||
"assets/icons/automation_functions/residual_electricity.svg";
|
||||
static const String hijackAlarm =
|
||||
"assets/icons/automation_functions/hijack_alarm.svg";
|
||||
static const String passwordUnlock =
|
||||
"assets/icons/automation_functions/password_unlock.svg";
|
||||
static const String remoteUnlockRequest =
|
||||
"assets/icons/automation_functions/remote_unlock_req.svg";
|
||||
static const String cardUnlock =
|
||||
"assets/icons/automation_functions/card_unlock.svg";
|
||||
static const String tempPasswordUnlock = "assets/icons/automation_functions/temp_password_unlock.svg";
|
||||
static const String doorlockNormalOpen = "assets/icons/automation_functions/doorlock_normal_open.svg";
|
||||
static const String doorbell = "assets/icons/automation_functions/doorbell.svg";
|
||||
static const String remoteUnlockViaApp = "assets/icons/automation_functions/remote_unlock_via_app.svg";
|
||||
static const String doubleLock = "assets/icons/automation_functions/double_lock.svg";
|
||||
static const String selfTestResult = "assets/icons/automation_functions/self_test_result.svg";
|
||||
static const String lockAlarm = "assets/icons/automation_functions/lock_alarm.svg";
|
||||
static const String presenceState = "assets/icons/automation_functions/presence_state.svg";
|
||||
static const String currentTemp = "assets/icons/automation_functions/current_temp.svg";
|
||||
static const String presence = "assets/icons/automation_functions/presence.svg";
|
||||
static const String residualElectricity = "assets/icons/automation_functions/residual_electricity.svg";
|
||||
static const String hijackAlarm = "assets/icons/automation_functions/hijack_alarm.svg";
|
||||
static const String passwordUnlock = "assets/icons/automation_functions/password_unlock.svg";
|
||||
static const String remoteUnlockRequest = "assets/icons/automation_functions/remote_unlock_req.svg";
|
||||
static const String cardUnlock = "assets/icons/automation_functions/card_unlock.svg";
|
||||
static const String motion = "assets/icons/automation_functions/motion.svg";
|
||||
static const String fingerprintUnlock =
|
||||
"assets/icons/automation_functions/fingerprint_unlock.svg";
|
||||
static const String fingerprintUnlock = "assets/icons/automation_functions/fingerprint_unlock.svg";
|
||||
|
||||
// Presence Sensor Assets
|
||||
static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg";
|
||||
static const String sensorPresenceIcon =
|
||||
"assets/icons/sensor_presence_ic.svg";
|
||||
static const String sensorPresenceIcon = "assets/icons/sensor_presence_ic.svg";
|
||||
static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg";
|
||||
static const String illuminanceRecordIcon =
|
||||
"assets/icons/illuminance_record_ic.svg";
|
||||
static const String presenceRecordIcon =
|
||||
"assets/icons/presence_record_ic.svg";
|
||||
static const String helpDescriptionIcon =
|
||||
"assets/icons/help_description_ic.svg";
|
||||
static const String illuminanceRecordIcon = "assets/icons/illuminance_record_ic.svg";
|
||||
static const String presenceRecordIcon = "assets/icons/presence_record_ic.svg";
|
||||
static const String helpDescriptionIcon = "assets/icons/help_description_ic.svg";
|
||||
|
||||
static const String lightPulp = "assets/icons/light_pulb.svg";
|
||||
static const String acDevice = "assets/icons/ac_device.svg";
|
||||
@ -172,4 +147,7 @@ class Assets {
|
||||
|
||||
//assets/icons/ac_schedule.svg
|
||||
static const String acSchedule = 'assets/icons/ac_schedule.svg';
|
||||
|
||||
//assets/icons/preferences.svg
|
||||
static const String preferences = 'assets/icons/preferences.svg';
|
||||
}
|
||||
|
Reference in New Issue
Block a user