mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-03-11 01:21:43 +00:00
Compare commits
35 Commits
SP-1285-FE
...
changed_ti
| Author | SHA1 | Date | |
|---|---|---|---|
| 214ec78a95 | |||
| ed9f98e653 | |||
| a37236c8d2 | |||
| e7efd2b3a1 | |||
| 2b0e504f05 | |||
| a656d5981e | |||
| 3f49a18130 | |||
| a51c4d9679 | |||
| caeed8e73f | |||
| dc5ac9be5b | |||
| 5c9b30895f | |||
| 06b14a3964 | |||
| 3c92ea3047 | |||
| cb79627038 | |||
| 9e84048f81 | |||
| 99adb1c286 | |||
| f2412aa867 | |||
| e4768c95aa | |||
| f25b4dbf6d | |||
| 9eff9ab371 | |||
| a2e68d6194 | |||
| 94c94b170f | |||
| 253cf15559 | |||
| 443eea9421 | |||
| 87a2c08f64 | |||
| dd66e7c747 | |||
| 7af61d2f65 | |||
| f37eacb0ee | |||
| c7dcc297aa | |||
| aefe5ad081 | |||
| 8d9af8519d | |||
| b1d52937c9 | |||
| 5fedf37421 | |||
| 4c8f2c72df | |||
| fb867e5df3 |
2
.env.dev
2
.env.dev
@ -1,3 +1,5 @@
|
||||
ENV_NAME=development
|
||||
BASE_URL=https://syncrow-dev.azurewebsites.net
|
||||
PROJECT_ID=0e62577c-06fa-41b9-8a92-99a21fbaf51c
|
||||
CLIENT_ID=c024573d191a327ce74db7d4502fdc29
|
||||
CLIENT_SECRET=fec6ccbc33664f94a3b84a45c7cceef3f3ebd1613ef4307db8946ede530cd1ed
|
||||
10
assets/icons/cancel_icon.svg
Normal file
10
assets/icons/cancel_icon.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7302_4118)">
|
||||
<path d="M11.1049 10.0001L19.7712 1.33381C20.0763 1.02869 20.0763 0.534007 19.7712 0.228929C19.4661 -0.0761485 18.9714 -0.0761876 18.6663 0.228929L9.99999 8.89524L1.33372 0.228929C1.0286 -0.0761876 0.533915 -0.0761876 0.228837 0.228929C-0.0762401 0.534046 -0.0762792 1.02873 0.228837 1.33381L8.89511 10.0001L0.228837 18.6664C-0.0762792 18.9715 -0.0762792 19.4662 0.228837 19.7713C0.381376 19.9238 0.581337 20.0001 0.781297 20.0001C0.981258 20.0001 1.18118 19.9238 1.33376 19.7713L9.99999 11.105L18.6663 19.7713C18.8188 19.9238 19.0188 20.0001 19.2187 20.0001C19.4187 20.0001 19.6186 19.9238 19.7712 19.7713C20.0763 19.4662 20.0763 18.9715 19.7712 18.6664L11.1049 10.0001Z" fill="#999999"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7302_4118">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 939 B |
10
assets/icons/save_routines_icon.svg
Normal file
10
assets/icons/save_routines_icon.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7302_4149)">
|
||||
<path d="M19.9969 4.94279C19.986 4.83232 19.943 4.72146 19.8674 4.62924C19.8382 4.59358 20.1367 4.89431 15.4141 0.17176C15.3015 0.0591838 15.1487 8.30277e-05 14.9996 0.00012209C14.6443 0.00012209 2.11177 0.00012209 1.75779 0.00012209C0.788544 0.00012209 0 0.788666 0 1.75791V18.2421C0 19.2113 0.788544 19.9998 1.75779 19.9998H18.2419C19.2112 19.9998 19.9997 19.2113 19.9997 18.2421C19.9998 4.01624 20.0013 4.98771 19.9969 4.94279ZM13.4764 1.17198V5.00005C13.4764 5.32314 13.2136 5.58598 12.8905 5.58598H12.1483V1.17198H13.4764ZM10.9765 1.17198V5.58598H5.54684C5.22376 5.58598 4.96091 5.32314 4.96091 5.00005V1.17198H10.9765ZM13.4764 12.539H4.96091V11.7968C4.96091 11.4738 5.22376 11.2109 5.54684 11.2109H12.8905C13.2136 11.2109 13.4764 11.4738 13.4764 11.7968V12.539ZM4.96091 18.828V13.7109H13.4764V18.828H4.96091ZM18.8279 18.2421C18.8279 18.5651 18.5651 18.828 18.242 18.828H14.6483C14.6483 18.0641 14.6483 12.6676 14.6483 11.7968C14.6483 10.8276 13.8597 10.039 12.8905 10.039H5.54684C4.57759 10.039 3.78905 10.8276 3.78905 11.7968V18.828H1.75783C1.43475 18.828 1.1719 18.5651 1.1719 18.2421V1.75791C1.1719 1.43483 1.43475 1.17198 1.75783 1.17198H3.78905V5.00005C3.78905 5.9693 4.57759 6.75784 5.54684 6.75784H12.8905C13.8597 6.75784 14.6483 5.9693 14.6483 5.00005V1.17198H14.7571L18.8279 5.24278V18.2421Z" fill="#023DFE" fill-opacity="0.6"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7302_4149">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:syncrow_app/features/auth/model/login_with_email_model.dart';
|
||||
import 'package:syncrow_app/features/auth/model/signup_model.dart';
|
||||
@ -217,9 +218,22 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
signUp() async {
|
||||
emit(AuthLoginLoading());
|
||||
final response;
|
||||
|
||||
final clientId = dotenv.env['CLIENT_ID'] ?? '';
|
||||
final clientSecret = dotenv.env['CLIENT_SECRET'] ?? '';
|
||||
|
||||
try {
|
||||
List<String> userFullName = fullName.split(' ');
|
||||
|
||||
final clientToken = await AuthenticationAPI.fetchClientToken(
|
||||
clientId: clientId,
|
||||
clientSecret: clientSecret,
|
||||
);
|
||||
|
||||
final accessToken = clientToken['accessToken'];
|
||||
|
||||
response = await AuthenticationAPI.signUp(
|
||||
accessToken: accessToken,
|
||||
model: SignUpModel(
|
||||
hasAcceptedAppAgreement: true,
|
||||
email: email.toLowerCase(),
|
||||
|
||||
@ -178,6 +178,7 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
||||
DeviceType.CeilingSensor,
|
||||
DeviceType.ThreeGang,
|
||||
DeviceType.OneGang,
|
||||
DeviceType.TwoGang
|
||||
};
|
||||
|
||||
return devices
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart';
|
||||
@ -31,7 +29,7 @@ class SixSceneScreen extends StatelessWidget {
|
||||
..add(const SexSceneSwitchInitial()),
|
||||
child: BlocBuilder<SixSceneBloc, SixSceneState>(
|
||||
builder: (context, state) {
|
||||
final _bloc = BlocProvider.of<SixSceneBloc>(context);
|
||||
final bloc = BlocProvider.of<SixSceneBloc>(context);
|
||||
SixSceneModel model = SixSceneModel(
|
||||
scene_1: '',
|
||||
scene_2: '',
|
||||
@ -48,7 +46,7 @@ class SixSceneScreen extends StatelessWidget {
|
||||
model = state.device;
|
||||
}
|
||||
return DefaultScaffold(
|
||||
title: _bloc.deviceInfo.name,
|
||||
title: device?.name ?? '6 Scene Switch',
|
||||
actions: [
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
@ -58,9 +56,9 @@ class SixSceneScreen extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
if (val == null) {
|
||||
_bloc.add(const SixSceneInitialInfo());
|
||||
_bloc.add(const SixSceneInitial());
|
||||
_bloc.add(const SexSceneSwitchInitial());
|
||||
bloc.add(const SixSceneInitialInfo());
|
||||
bloc.add(const SixSceneInitial());
|
||||
bloc.add(const SexSceneSwitchInitial());
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(Assets.assetsIconsSettings),
|
||||
@ -77,7 +75,7 @@ class SixSceneScreen extends StatelessWidget {
|
||||
)
|
||||
: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
_bloc.add(const SixSceneInitial());
|
||||
bloc.add(const SixSceneInitial());
|
||||
},
|
||||
child: ListView(
|
||||
children: [
|
||||
@ -92,22 +90,22 @@ class SixSceneScreen extends StatelessWidget {
|
||||
switch4Title: model.scene_4,
|
||||
switch5Title: model.scene_5,
|
||||
switch6Title: model.scene_6,
|
||||
switch1Down: _bloc.deviceStatus.switch_backlight
|
||||
switch1Down: bloc.deviceStatus.switch_backlight
|
||||
? Assets.switchOn
|
||||
: Assets.switchOff,
|
||||
switch1Up: _bloc.deviceStatus.switch_backlight
|
||||
switch1Up: bloc.deviceStatus.switch_backlight
|
||||
? Assets.switchOn
|
||||
: Assets.switchOff,
|
||||
switch2Down: _bloc.deviceStatus.switch_backlight
|
||||
switch2Down: bloc.deviceStatus.switch_backlight
|
||||
? Assets.switchOn
|
||||
: Assets.switchOff,
|
||||
switch2Up: _bloc.deviceStatus.switch_backlight
|
||||
switch2Up: bloc.deviceStatus.switch_backlight
|
||||
? Assets.switchOn
|
||||
: Assets.switchOff,
|
||||
switch3Up: _bloc.deviceStatus.switch_backlight
|
||||
switch3Up: bloc.deviceStatus.switch_backlight
|
||||
? Assets.switchOn
|
||||
: Assets.switchOff,
|
||||
switch3Down: _bloc.deviceStatus.switch_backlight
|
||||
switch3Down: bloc.deviceStatus.switch_backlight
|
||||
? Assets.switchOn
|
||||
: Assets.switchOff,
|
||||
onSwitch3DownTap: () {
|
||||
@ -135,7 +133,7 @@ class SixSceneScreen extends StatelessWidget {
|
||||
Expanded(
|
||||
child: DefaultContainer(
|
||||
onTap: () {
|
||||
_bloc.add(ChangeSwitchStatusEvent());
|
||||
bloc.add(ChangeSwitchStatusEvent());
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
@ -197,9 +195,9 @@ class SixSceneScreen extends StatelessWidget {
|
||||
);
|
||||
if (value == true) {
|
||||
Future.delayed(
|
||||
const Duration(
|
||||
milliseconds: 200), () {
|
||||
_bloc.add(
|
||||
const Duration(milliseconds: 200),
|
||||
() {
|
||||
bloc.add(
|
||||
const SexSceneSwitchInitial());
|
||||
});
|
||||
}
|
||||
|
||||
@ -22,14 +22,15 @@ class DoorSensorScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'Door Sensor',
|
||||
title: device?.name,
|
||||
child: BlocProvider(
|
||||
create: (context) =>
|
||||
DoorSensorBloc(DSId: device?.uuid ?? '')..add(const DoorSensorInitial()),
|
||||
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
||||
builder: (context, state) {
|
||||
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
||||
DoorSensorModel model = DoorSensorModel(batteryPercentage: 0, doorContactState: false);
|
||||
DoorSensorModel model =
|
||||
DoorSensorModel(batteryPercentage: 0, doorContactState: false);
|
||||
if (state is LoadingNewSate) {
|
||||
model = state.doorSensor;
|
||||
} else if (state is UpdateState) {
|
||||
@ -37,8 +38,8 @@ class DoorSensorScreen extends StatelessWidget {
|
||||
}
|
||||
return state is DoorSensorLoadingState
|
||||
? const Center(
|
||||
child:
|
||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||
child: DefaultContainer(
|
||||
width: 50, height: 50, child: CircularProgressIndicator()),
|
||||
)
|
||||
: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
@ -56,7 +57,8 @@ class DoorSensorScreen extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: InkWell(
|
||||
overlayColor: WidgetStateProperty.all(Colors.transparent),
|
||||
overlayColor:
|
||||
WidgetStateProperty.all(Colors.transparent),
|
||||
onTap: () {},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -107,17 +109,21 @@ class DoorSensorScreen extends StatelessWidget {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
DoorRecordsScreen(DSId: device!.uuid!)),
|
||||
DoorRecordsScreen(
|
||||
DSId: device!.uuid!)),
|
||||
);
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints:
|
||||
const BoxConstraints(maxHeight: 46, maxWidth: 50),
|
||||
child: SvgPicture.asset(Assets.doorRecordsIcon),
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: 46, maxWidth: 50),
|
||||
child: SvgPicture.asset(
|
||||
Assets.doorRecordsIcon),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
@ -143,18 +149,21 @@ class DoorSensorScreen extends StatelessWidget {
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => NotificationSettingsPage()),
|
||||
builder: (context) =>
|
||||
NotificationSettingsPage()),
|
||||
);
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints:
|
||||
const BoxConstraints(maxHeight: 46, maxWidth: 50),
|
||||
child:
|
||||
SvgPicture.asset(Assets.doorNotificationSetting),
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: 46, maxWidth: 50),
|
||||
child: SvgPicture.asset(
|
||||
Assets.doorNotificationSetting),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
|
||||
@ -47,7 +47,7 @@ class FourSceneScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
return DefaultScaffold(
|
||||
title: _bloc.deviceInfo.name,
|
||||
title: device?.name ?? '4 Scene',
|
||||
actions: [
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
@ -165,7 +165,7 @@ class FourSceneScreen extends StatelessWidget {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
confirmTab:
|
||||
(switchSelected) async {
|
||||
(switchSelected) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
|
||||
@ -21,7 +21,8 @@ class GateWayView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => GatewayBloc()..add(GatewayInitial(gatewayId: gatewayObj.uuid ?? '')),
|
||||
create: (context) =>
|
||||
GatewayBloc()..add(GatewayInitial(gatewayId: gatewayObj.uuid ?? '')),
|
||||
child: BlocBuilder<GatewayBloc, GatewayState>(builder: (context, state) {
|
||||
List<DeviceModel> devicesList = [];
|
||||
if (state is UpdateGatewayState) {
|
||||
@ -37,7 +38,7 @@ class GateWayView extends StatelessWidget {
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: DeviceAppbar(
|
||||
deviceName: 'Gateway',
|
||||
deviceName: gatewayObj.name ?? 'Gateway',
|
||||
deviceUuid: gatewayObj.uuid!,
|
||||
),
|
||||
body: Container(
|
||||
@ -60,7 +61,7 @@ class GateWayView extends StatelessWidget {
|
||||
},
|
||||
child: ListView(
|
||||
children: [
|
||||
Container(
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
@ -90,7 +91,8 @@ class GateWayView extends StatelessWidget {
|
||||
),
|
||||
]),
|
||||
),
|
||||
if (devicesList.isEmpty && state is UpdateGatewayState)
|
||||
if (devicesList.isEmpty &&
|
||||
state is UpdateGatewayState)
|
||||
Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
alignment: AlignmentDirectional.center,
|
||||
@ -115,7 +117,8 @@ class GateWayView extends StatelessWidget {
|
||||
margin: const EdgeInsets.only(top: 20),
|
||||
height: 50,
|
||||
width: 50,
|
||||
child: const RefreshProgressIndicator()),
|
||||
child:
|
||||
const RefreshProgressIndicator()),
|
||||
)
|
||||
: Expanded(
|
||||
child: GridView.builder(
|
||||
@ -130,7 +133,8 @@ class GateWayView extends StatelessWidget {
|
||||
shrinkWrap: true,
|
||||
itemCount: devicesList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return RoomPageSwitch(device: devicesList[index]);
|
||||
return RoomPageSwitch(
|
||||
device: devicesList[index]);
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@ -51,7 +51,7 @@ class _PowerClampPageState extends State<PowerClampPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'Power Clamp',
|
||||
title: widget.device?.name ?? 'Power Clamp',
|
||||
child: BlocProvider(
|
||||
create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
|
||||
..add(const PowerClampInitial()),
|
||||
@ -153,41 +153,6 @@ class _PowerClampPageState extends State<PowerClampPage> {
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _buildPowerClampCards(PowerClampModel model,
|
||||
List<EnergyData> chartData, PowerClampBloc blocProvider) {
|
||||
return [
|
||||
_buildPowerClampCard(
|
||||
phaseType: '',
|
||||
title: 'Total Energy \nConsumption',
|
||||
phase: model.status.general,
|
||||
isGeneral: true,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
phaseType: 'Phase A consumption',
|
||||
title: 'Phase A Energy \nConsumption',
|
||||
phase: model.status.phaseA,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
phaseType: 'Phase B consumption',
|
||||
title: 'Phase B Energy \nConsumption',
|
||||
phase: model.status.phaseB,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
phaseType: 'Phase C consumption',
|
||||
title: 'Phase C Energy \nConsumption',
|
||||
phase: model.status.phaseC,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Widget _buildPowerClampCard({
|
||||
required String title,
|
||||
required String phaseType,
|
||||
@ -209,10 +174,8 @@ class _PowerClampPageState extends State<PowerClampPage> {
|
||||
blocProvider.add(SelectDateEvent(context: context));
|
||||
},
|
||||
totalActiveGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
|
||||
totalCurrentGeneral:
|
||||
isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
|
||||
totalFrequencyGeneral:
|
||||
isGeneral ? _getValueOrNA(phase.dataPoints, 4) : null,
|
||||
totalCurrentGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
|
||||
totalFrequencyGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 4) : null,
|
||||
totalFactor: !isGeneral ? _getValueOrNA(phase.dataPoints, 3) : null,
|
||||
totalActive: !isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
|
||||
totalCurrent: !isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
|
||||
@ -223,9 +186,7 @@ class _PowerClampPageState extends State<PowerClampPage> {
|
||||
}
|
||||
|
||||
String _getValueOrNA(List<DataPoint> dataPoints, int index) {
|
||||
return dataPoints.length > index
|
||||
? dataPoints[index].value.toString()
|
||||
: 'N/A';
|
||||
return dataPoints.length > index ? dataPoints[index].value.toString() : 'N/A';
|
||||
}
|
||||
|
||||
Widget _buildPageIndicator() {
|
||||
@ -240,8 +201,7 @@ class _PowerClampPageState extends State<PowerClampPage> {
|
||||
height: 10.0,
|
||||
width: _currentPage == index ? 10.0 : 10.0,
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
_currentPage == index ? Colors.grey : ColorsManager.greyColor,
|
||||
color: _currentPage == index ? Colors.grey : ColorsManager.greyColor,
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
),
|
||||
);
|
||||
|
||||
@ -10,6 +10,7 @@ import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/door_sensor/door_sensor_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart';
|
||||
@ -19,14 +20,13 @@ import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_touch/one_touch_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_touch/three_touch_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/water_heater/water_heater_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/water_leak/water_leak_screen.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
|
||||
@ -73,34 +73,30 @@ class RoomPageSwitch extends StatelessWidget {
|
||||
? CustomSwitch(
|
||||
device: device,
|
||||
)
|
||||
: const SizedBox(),
|
||||
: const SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
Flexible(
|
||||
child: FittedBox(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
device.name ?? "",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
device.subspace!.subspaceName ?? '',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.bodySmall.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 10,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
Text(
|
||||
device.name ?? '',
|
||||
textScaler: TextScaler.linear(1),
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey,
|
||||
fontSize: 14,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: Text(
|
||||
device.subspace!.subspaceName ?? '',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textScaler: TextScaler.linear(1),
|
||||
style: context.bodySmall.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 9,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -119,8 +115,6 @@ Future<void> showDeviceInterface(
|
||||
required BuildContext context,
|
||||
required isAllDevices,
|
||||
List<DeviceModel>? allDevices}) async {
|
||||
print('object-----${device.uuid} ${device.name}');
|
||||
|
||||
final devicesCubit = context.read<DevicesCubit>();
|
||||
|
||||
switch (device.productType) {
|
||||
|
||||
@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/sos_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_alarm_management_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_records_screen.dart';
|
||||
@ -29,17 +28,8 @@ class SosScreen extends StatelessWidget {
|
||||
child: BlocBuilder<SosBloc, SosState>(
|
||||
builder: (context, state) {
|
||||
final sensor = BlocProvider.of<SosBloc>(context);
|
||||
SosModel model = SosModel(
|
||||
batteryPercentage: 0,
|
||||
sosContactState: '',
|
||||
);
|
||||
if (state is LoadingNewSate) {
|
||||
model = state.sosSensor;
|
||||
} else if (state is UpdateState) {
|
||||
model = state.sensor;
|
||||
}
|
||||
return DefaultScaffold(
|
||||
title: sensor.deviceInfo.name,
|
||||
title: device?.name,
|
||||
actions: [
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
@ -82,38 +72,33 @@ class SosScreen extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: InkWell(
|
||||
overlayColor: MaterialStateProperty.all(
|
||||
Colors.transparent),
|
||||
overlayColor:
|
||||
WidgetStateProperty.all(Colors.transparent),
|
||||
onTap: () {
|
||||
// Add functionality for the main SOS button here
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(890),
|
||||
borderRadius: BorderRadius.circular(890),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color:
|
||||
Colors.white.withOpacity(0.1),
|
||||
color: Colors.white.withOpacity(0.1),
|
||||
blurRadius: 24,
|
||||
offset: const Offset(-5, -5),
|
||||
blurStyle: BlurStyle.outer,
|
||||
),
|
||||
BoxShadow(
|
||||
color: Colors.black
|
||||
.withOpacity(0.11),
|
||||
color: Colors.black.withOpacity(0.11),
|
||||
blurRadius: 25,
|
||||
offset: const Offset(5, 5),
|
||||
blurStyle: BlurStyle.outer,
|
||||
),
|
||||
BoxShadow(
|
||||
color: Colors.black
|
||||
.withOpacity(0.13),
|
||||
color: Colors.black.withOpacity(0.13),
|
||||
blurRadius: 30,
|
||||
offset: const Offset(5, 5),
|
||||
blurStyle: BlurStyle.inner,
|
||||
@ -140,9 +125,8 @@ class SosScreen extends StatelessWidget {
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
SosRecordsScreen(
|
||||
sosId: device!.uuid!),
|
||||
builder: (context) => SosRecordsScreen(
|
||||
sosId: device!.uuid!),
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -197,8 +181,8 @@ class SosScreen extends StatelessWidget {
|
||||
maxHeight: 46,
|
||||
maxWidth: 50,
|
||||
),
|
||||
child: SvgPicture.asset(Assets
|
||||
.doorNotificationSetting),
|
||||
child: SvgPicture.asset(
|
||||
Assets.doorNotificationSetting),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
const Flexible(
|
||||
|
||||
@ -9,7 +9,10 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class GangSwitch extends StatelessWidget {
|
||||
const GangSwitch(
|
||||
{super.key, required this.threeGangSwitch, required this.value, required this.action});
|
||||
{super.key,
|
||||
required this.threeGangSwitch,
|
||||
required this.value,
|
||||
required this.action});
|
||||
|
||||
final DeviceModel threeGangSwitch;
|
||||
final bool value;
|
||||
|
||||
@ -21,7 +21,7 @@ class WaterHeaterPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'Water heater',
|
||||
title: device?.name?? 'Water heater',
|
||||
child: BlocProvider(
|
||||
create: (context) => WaterHeaterBloc(switchCode: 'switch_1', whId: device?.uuid ?? '')
|
||||
..add(const WaterHeaterInitial()),
|
||||
|
||||
@ -22,7 +22,7 @@ class WaterLeakScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'Water Leak Sensor',
|
||||
title: device?.name ?? 'Water Leak',
|
||||
child: BlocProvider(
|
||||
create: (context) => WaterLeakBloc(WLId: device?.uuid ?? '')
|
||||
..add(const WaterLeakInitial()),
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_event.dart';
|
||||
@ -7,19 +5,31 @@ import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart
|
||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart';
|
||||
|
||||
class TabBarBloc extends Bloc<TabBarEvent, TabBarState> {
|
||||
final DeviceManagerBloc deviceManagerBloc;
|
||||
TabBarBloc(this.deviceManagerBloc) : super(const Initial()) {
|
||||
on<TabChanged>(_handleTabChanged);
|
||||
TabBarBloc(this.deviceManagerBloc) : super(const TabBarInitialState()) {
|
||||
on<TabBarTabChangedEvent>(_onTabBarTabChangedEvent);
|
||||
}
|
||||
|
||||
FutureOr<void> _handleTabChanged(
|
||||
TabChanged event, Emitter<TabBarState> emit) {
|
||||
final DeviceManagerBloc deviceManagerBloc;
|
||||
|
||||
void _onTabBarTabChangedEvent(
|
||||
TabBarTabChangedEvent event,
|
||||
Emitter<TabBarState> emit,
|
||||
) {
|
||||
_getDevices(event);
|
||||
|
||||
emit(
|
||||
TabBarTabSelectedState(
|
||||
roomId: event.roomId,
|
||||
selectedTabIndex: event.selectedIndex,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _getDevices(TabBarTabChangedEvent event) {
|
||||
if (event.roomId == "-1") {
|
||||
deviceManagerBloc.add(FetchAllDevices());
|
||||
} else {
|
||||
deviceManagerBloc.add(FetchDevicesByRoomId(event.roomId,event.unit));
|
||||
deviceManagerBloc.add(FetchDevicesByRoomId(event.roomId, event.unit));
|
||||
}
|
||||
emit(TabSelected(
|
||||
roomId: event.roomId, selectedTabIndex: event.selectedIndex));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,10 +4,14 @@ abstract class TabBarEvent {
|
||||
const TabBarEvent();
|
||||
}
|
||||
|
||||
class TabChanged extends TabBarEvent {
|
||||
class TabBarTabChangedEvent extends TabBarEvent {
|
||||
const TabBarTabChangedEvent({
|
||||
required this.selectedIndex,
|
||||
required this.roomId,
|
||||
required this.unit,
|
||||
});
|
||||
|
||||
final int selectedIndex;
|
||||
final String roomId;
|
||||
final SpaceModel unit;
|
||||
const TabChanged(
|
||||
{required this.selectedIndex, required this.roomId, required this.unit});
|
||||
}
|
||||
|
||||
@ -2,12 +2,16 @@ abstract class TabBarState {
|
||||
const TabBarState();
|
||||
}
|
||||
|
||||
class Initial extends TabBarState {
|
||||
const Initial();
|
||||
class TabBarInitialState extends TabBarState {
|
||||
const TabBarInitialState();
|
||||
}
|
||||
|
||||
class TabSelected extends TabBarState {
|
||||
class TabBarTabSelectedState extends TabBarState {
|
||||
const TabBarTabSelectedState({
|
||||
required this.roomId,
|
||||
required this.selectedTabIndex,
|
||||
});
|
||||
|
||||
final int selectedTabIndex;
|
||||
final String roomId;
|
||||
const TabSelected({required this.roomId, required this.selectedTabIndex});
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ class ThreeGangHelperFunctions {
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'Light 1 Switch',
|
||||
operationName: 'L - Light Switch',
|
||||
code: 'switch_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
@ -21,11 +21,23 @@ class ThreeGangHelperFunctions {
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'L - Light Countdown',
|
||||
code: 'countdown_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.countdown,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(icon: '', value: 0),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'Light 2 Switch',
|
||||
operationName: 'M - Light Switch',
|
||||
code: 'switch_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
@ -36,11 +48,23 @@ class ThreeGangHelperFunctions {
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'M - Light Countdown',
|
||||
code: 'countdown_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.countdown,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(icon: '', value: 0),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'Light 3 Switch',
|
||||
operationName: 'R - Light Switch',
|
||||
code: 'switch_3',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
@ -55,31 +79,7 @@ class ThreeGangHelperFunctions {
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'Light 1 CountDown',
|
||||
code: 'countdown_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.countdown,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(icon: '', value: 0),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'Light 2 CountDown',
|
||||
code: 'countdown_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.countdown,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(icon: '', value: 0),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'Light 3 CountDown',
|
||||
operationName: 'R - Light Countdown',
|
||||
code: 'countdown_3',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.countdown,
|
||||
@ -97,7 +97,7 @@ class ThreeGangHelperFunctions {
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'Light 1 Switch',
|
||||
operationName: 'L - Light Switch',
|
||||
code: 'switch_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
@ -108,41 +108,11 @@ class ThreeGangHelperFunctions {
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'Light 2 Switch',
|
||||
code: 'switch_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'Light 3 Switch',
|
||||
code: 'switch_3',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'Light 1 CountDown',
|
||||
operationName: 'L - Light Countdown',
|
||||
code: 'countdown_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.integerSteps,
|
||||
@ -157,11 +127,26 @@ class ThreeGangHelperFunctions {
|
||||
),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'M - Light Switch',
|
||||
code: 'switch_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'Light 2 CountDown',
|
||||
operationName: 'M - Light Countdown',
|
||||
code: 'countdown_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.integerSteps,
|
||||
@ -176,11 +161,26 @@ class ThreeGangHelperFunctions {
|
||||
),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'R - Light Switch',
|
||||
code: 'switch_3',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'Light 3 CountDown',
|
||||
operationName: 'R - Light Countdown',
|
||||
code: 'countdown_3',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.integerSteps,
|
||||
|
||||
@ -0,0 +1,139 @@
|
||||
import 'package:syncrow_app/features/scene/enum/operation_dialog_type.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
class TowGangHelperFunctions {
|
||||
static List<SceneStaticFunction> towGangHelperFunctions(
|
||||
String deviceId, String deviceName, functionValue) {
|
||||
return [
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'L - Light Switch',
|
||||
code: 'switch_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'L - Light CountDown',
|
||||
code: 'countdown_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.countdown,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(icon: '', value: 0),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'R - Light Switch',
|
||||
code: 'switch_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'R - Light CountDown',
|
||||
code: 'countdown_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.countdown,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(icon: '', value: 0),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
static List<SceneStaticFunction> towGangAutomationFunctions(
|
||||
String deviceId, String deviceName, functionValue) {
|
||||
return [
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'L - Light Switch',
|
||||
code: 'switch_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'R - Light CountDown',
|
||||
code: 'countdown_1',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.integerSteps,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
operationName: 'R - Light Switch',
|
||||
code: 'switch_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.onOff,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPower, description: "ON", value: true),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF, description: "OFF", value: false),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
operationName: 'R - Light CountDown',
|
||||
code: 'countdown_2',
|
||||
functionValue: functionValue,
|
||||
operationDialogType: OperationDialogType.integerSteps,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import 'package:syncrow_app/features/scene/helper/functions_per_device/human_pre
|
||||
import 'package:syncrow_app/features/scene/helper/functions_per_device/one_gang_functions.dart';
|
||||
import 'package:syncrow_app/features/scene/helper/functions_per_device/presence_sensor.dart';
|
||||
import 'package:syncrow_app/features/scene/helper/functions_per_device/three_gang_functions.dart';
|
||||
import 'package:syncrow_app/features/scene/helper/functions_per_device/tow_gang_helper_functions.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_details_model.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
@ -27,6 +28,7 @@ mixin SceneOperationsDataHelper {
|
||||
DeviceType.ThreeGang: threeGangFunctions,
|
||||
DeviceType.Gateway: gatewayFunctions,
|
||||
DeviceType.OneGang: oneGangFunctions,
|
||||
DeviceType.TwoGang: towGangFunctions,
|
||||
};
|
||||
|
||||
final Map<DeviceType, String> _titleMap = {
|
||||
@ -39,8 +41,8 @@ mixin SceneOperationsDataHelper {
|
||||
DeviceType.ThreeGang: '3G Light Switch Functions',
|
||||
DeviceType.Gateway: 'Gateway Functions',
|
||||
DeviceType.OneGang: '1G Light Switch Conditions',
|
||||
DeviceType.TwoGang: '2G Light Switch Conditions',
|
||||
};
|
||||
static String _productTypeCache = '';
|
||||
|
||||
//one gang functions
|
||||
static List<SceneStaticFunction> oneGangFunctions(
|
||||
@ -57,6 +59,20 @@ mixin SceneOperationsDataHelper {
|
||||
deviceId, deviceName, functionValue);
|
||||
}
|
||||
|
||||
static List<SceneStaticFunction> towGangFunctions(
|
||||
List<FunctionModel> functions,
|
||||
String deviceId,
|
||||
String deviceName,
|
||||
dynamic functionValue,
|
||||
bool isAutomation) {
|
||||
if (isAutomation) {
|
||||
return TowGangHelperFunctions.towGangAutomationFunctions(
|
||||
deviceId, deviceName, functionValue);
|
||||
}
|
||||
return TowGangHelperFunctions.towGangHelperFunctions(
|
||||
deviceId, deviceName, functionValue);
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> getFunctionsWithIcons({
|
||||
DeviceType? type,
|
||||
required List<FunctionModel> functions,
|
||||
@ -243,6 +259,8 @@ mixin SceneOperationsDataHelper {
|
||||
for (var condition in conditions) {
|
||||
// Create a dummy Action from Condition to reuse _mapExecutorPropertyToSceneFunction
|
||||
Action dummyAction = Action(
|
||||
deviceName: condition.deviceName,
|
||||
productType: condition.productType,
|
||||
actionExecutor: 'device_report',
|
||||
entityId: condition.entityId,
|
||||
executorProperty: ExecutorProperty(
|
||||
@ -352,7 +370,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Sensitivity',
|
||||
isAutomation
|
||||
@ -369,7 +387,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Set Door lock Normal Open',
|
||||
OperationDialogType.onOff,
|
||||
@ -423,7 +441,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Fingerprint Unlock',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -438,7 +456,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Password Unlock',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -453,7 +471,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Card Unlock',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -468,7 +486,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Lock Alarm',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -483,7 +501,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Remote Unlock Request',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -498,7 +516,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Residual Electricity',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -513,7 +531,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Double Lock',
|
||||
OperationDialogType.onOff,
|
||||
@ -528,7 +546,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Remote Unlock Via App',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -543,7 +561,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Hijack Alarm',
|
||||
OperationDialogType.onOff,
|
||||
@ -558,7 +576,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Doorbell',
|
||||
OperationDialogType.onOff,
|
||||
@ -573,7 +591,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'WIFI LOCK PRO',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsDoorLock,
|
||||
'Temporary Password Unlock',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -588,7 +606,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Far Detection',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -603,7 +621,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Motion Detection Sensitivity',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -618,7 +636,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Motionless Detection Sensitivity',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -633,7 +651,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Indicator',
|
||||
OperationDialogType.onOff,
|
||||
@ -648,7 +666,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Nobody Time',
|
||||
OperationDialogType.countdown,
|
||||
@ -663,7 +681,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Presence State',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -678,7 +696,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Current Distance',
|
||||
isAutomation
|
||||
@ -695,7 +713,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Illuminance Value',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -710,7 +728,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Human Presence Sensor',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsSensors,
|
||||
'Self-Test Result',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -725,7 +743,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Smart AC Thermostat - Grey - Model A',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsAC,
|
||||
'Power',
|
||||
OperationDialogType.onOff,
|
||||
@ -740,7 +758,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Smart AC Thermostat - Grey - Model A',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsAC,
|
||||
'Set Temperature',
|
||||
isAutomation
|
||||
@ -759,7 +777,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Smart AC Thermostat - Grey - Model A',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsAC,
|
||||
'Current Temperature',
|
||||
OperationDialogType.integerSteps,
|
||||
@ -774,7 +792,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Smart AC Thermostat - Grey - Model A',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsAC,
|
||||
'Mode',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -789,7 +807,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Smart AC Thermostat - Grey - Model A',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsAC,
|
||||
'Fan Speed',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -804,7 +822,7 @@ mixin SceneOperationsDataHelper {
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Smart AC Thermostat - Grey - Model A',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsAC,
|
||||
'Child Lock',
|
||||
OperationDialogType.onOff,
|
||||
@ -821,7 +839,7 @@ mixin SceneOperationsDataHelper {
|
||||
case "3G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'3 Gang Button Switch L-L',
|
||||
action.deviceName,
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 1 Switch',
|
||||
OperationDialogType.onOff,
|
||||
@ -830,12 +848,36 @@ mixin SceneOperationsDataHelper {
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
case "2G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.twoGang,
|
||||
'Light 1 Switch',
|
||||
OperationDialogType.onOff,
|
||||
_createOnOffOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
case "1G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.oneGang,
|
||||
'Light 1 Switch',
|
||||
OperationDialogType.onOff,
|
||||
_createOnOffOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
default:
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'1 Gang Button Switch L-L',
|
||||
Assets.oneGang,
|
||||
'Light Switch',
|
||||
'None',
|
||||
Assets.assetsRemoteUnlockReq,
|
||||
'None',
|
||||
OperationDialogType.onOff,
|
||||
_createOnOffOptions(),
|
||||
isAutomation,
|
||||
@ -847,24 +889,51 @@ mixin SceneOperationsDataHelper {
|
||||
|
||||
SceneStaticFunction _createSwitch2Function(Action action, bool isAutomation,
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'3 Gang Button Switch L-L',
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 2 Switch',
|
||||
OperationDialogType.onOff,
|
||||
_createOnOffOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
switch (action.productType) {
|
||||
case "3G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 2 Switch',
|
||||
OperationDialogType.onOff,
|
||||
_createOnOffOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
case "2G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.twoGang,
|
||||
'Light 2 Switch',
|
||||
OperationDialogType.onOff,
|
||||
_createOnOffOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
default:
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.oneGang,
|
||||
'Light Switch',
|
||||
OperationDialogType.onOff,
|
||||
_createOnOffOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SceneStaticFunction _createSwitch3Function(Action action, bool isAutomation,
|
||||
String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'3 Gang Button Switch L-L',
|
||||
action.deviceName,
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 3 Switch',
|
||||
OperationDialogType.onOff,
|
||||
@ -881,7 +950,7 @@ mixin SceneOperationsDataHelper {
|
||||
case "3G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'3 Gang Button Switch L-L',
|
||||
action.deviceName,
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 1 CountDown',
|
||||
isAutomation
|
||||
@ -894,10 +963,26 @@ mixin SceneOperationsDataHelper {
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
case "2G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.twoGang,
|
||||
'Light 1 CountDown',
|
||||
isAutomation
|
||||
? OperationDialogType.integerSteps
|
||||
: OperationDialogType.countdown,
|
||||
isAutomation
|
||||
? _createAutomationCountDownOptions()
|
||||
: _createCountdownOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
default:
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'1 Gang Button Switch L-L',
|
||||
action.deviceName,
|
||||
Assets.oneGang,
|
||||
'Light CountDown',
|
||||
isAutomation
|
||||
@ -915,28 +1000,63 @@ mixin SceneOperationsDataHelper {
|
||||
|
||||
SceneStaticFunction _createCountdown2Function(Action action,
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'3 Gang Button Switch L-L',
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 2 CountDown',
|
||||
isAutomation
|
||||
? OperationDialogType.integerSteps
|
||||
: OperationDialogType.countdown,
|
||||
isAutomation
|
||||
? _createAutomationCountDownOptions()
|
||||
: _createCountdownOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
switch (action.productType) {
|
||||
case "3G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 2 CountDown',
|
||||
isAutomation
|
||||
? OperationDialogType.integerSteps
|
||||
: OperationDialogType.countdown,
|
||||
isAutomation
|
||||
? _createAutomationCountDownOptions()
|
||||
: _createCountdownOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
case "2G":
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.twoGang,
|
||||
'Light 2 CountDown',
|
||||
isAutomation
|
||||
? OperationDialogType.integerSteps
|
||||
: OperationDialogType.countdown,
|
||||
isAutomation
|
||||
? _createAutomationCountDownOptions()
|
||||
: _createCountdownOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
default:
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
action.deviceName,
|
||||
Assets.oneGang,
|
||||
'Light CountDown',
|
||||
isAutomation
|
||||
? OperationDialogType.integerSteps
|
||||
: OperationDialogType.countdown,
|
||||
isAutomation
|
||||
? _createAutomationCountDownOptions()
|
||||
: _createCountdownOptions(),
|
||||
isAutomation,
|
||||
comparator,
|
||||
uniqueCustomId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SceneStaticFunction _createCountdown3Function(Action action,
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'3 Gang Button Switch L-L',
|
||||
action.deviceName,
|
||||
Assets.assetsIcons3GangSwitch,
|
||||
'Light 3 CountDown',
|
||||
isAutomation
|
||||
@ -955,7 +1075,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Gateway',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsGateway,
|
||||
'Switch Alarm Sound',
|
||||
OperationDialogType.onOff,
|
||||
@ -970,7 +1090,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Gateway',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsGateway,
|
||||
'Master State',
|
||||
OperationDialogType.listOfOptions,
|
||||
@ -985,7 +1105,7 @@ mixin SceneOperationsDataHelper {
|
||||
bool isAutomation, String? comparator, String? uniqueCustomId) {
|
||||
return _createSceneFunction(
|
||||
action,
|
||||
'Gateway',
|
||||
action.deviceName,
|
||||
Assets.assetsIconsGateway,
|
||||
'Factory Reset',
|
||||
OperationDialogType.onOff,
|
||||
@ -1328,6 +1448,8 @@ mixin SceneOperationsDataHelper {
|
||||
return [
|
||||
_mapExecutorPropertyToSceneFunction(
|
||||
Action(
|
||||
deviceName: taskItem.deviceName,
|
||||
productType: '',
|
||||
entityId: deviceId,
|
||||
executorProperty: ExecutorProperty(
|
||||
functionCode: taskItem.code,
|
||||
|
||||
@ -74,7 +74,9 @@ class Action {
|
||||
ExecutorProperty? executorProperty;
|
||||
String? name;
|
||||
String? type;
|
||||
String? productType;
|
||||
final String productType;
|
||||
|
||||
final String deviceName;
|
||||
|
||||
Action({
|
||||
required this.actionExecutor,
|
||||
@ -82,7 +84,8 @@ class Action {
|
||||
this.executorProperty,
|
||||
this.name,
|
||||
this.type,
|
||||
this.productType,
|
||||
required this.productType,
|
||||
required this.deviceName,
|
||||
});
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
@ -94,7 +97,8 @@ class Action {
|
||||
entityId: json["entityId"] as String,
|
||||
name: json['name'] as String?,
|
||||
type: json['type'] as String?,
|
||||
productType: json['productType'] as String?,
|
||||
productType: json['productType'] as String,
|
||||
deviceName: json['deviceName'] as String,
|
||||
);
|
||||
}
|
||||
if (json["executorProperty"] == null) {
|
||||
@ -105,7 +109,8 @@ class Action {
|
||||
actionExecutor: json["actionExecutor"] as String,
|
||||
entityId: json["entityId"] as String,
|
||||
executorProperty: ExecutorProperty.fromJson(json["executorProperty"]),
|
||||
productType: json['productType'] as String?,
|
||||
productType: json['productType'] as String,
|
||||
deviceName: json['deviceName'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
@ -146,12 +151,16 @@ class Condition {
|
||||
final String entityId;
|
||||
final String entityType;
|
||||
final Expr expr;
|
||||
final String productType;
|
||||
final String deviceName;
|
||||
|
||||
Condition({
|
||||
required this.code,
|
||||
required this.entityId,
|
||||
required this.entityType,
|
||||
required this.expr,
|
||||
required this.productType,
|
||||
required this.deviceName,
|
||||
});
|
||||
|
||||
factory Condition.fromRawJson(String str) =>
|
||||
@ -164,6 +173,8 @@ class Condition {
|
||||
entityId: json["entityId"],
|
||||
entityType: json["entityType"],
|
||||
expr: Expr.fromJson(json["expr"]),
|
||||
productType: json['productType'] as String,
|
||||
deviceName: json['deviceName'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
@ -11,11 +12,10 @@ import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/light_divider.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/navigation/navigate_to_route.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class DeviceFunctionsView extends StatelessWidget
|
||||
@ -51,22 +51,14 @@ class DeviceFunctionsView extends StatelessWidget
|
||||
.add(AddTaskEvent(isAutomation: isAutomation));
|
||||
navigateToRoute(context, Routes.sceneTasksRoute);
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'Save',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.secondaryColor.withOpacity(0.6),
|
||||
),
|
||||
child: SvgPicture.asset(Assets.saveRoutinesIcon),
|
||||
),
|
||||
],
|
||||
leading: TextButton(
|
||||
onPressed: () {
|
||||
_cancelOperation(context, device, isAutomation);
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'Cancel',
|
||||
fontWeight: FontWeight.normal,
|
||||
fontColor: ColorsManager.textPrimaryColor.withOpacity(0.6),
|
||||
),
|
||||
child: SvgPicture.asset(Assets.cancelIcon),
|
||||
),
|
||||
leadingWidth: 80,
|
||||
padding: EdgeInsets.zero,
|
||||
@ -75,66 +67,127 @@ class DeviceFunctionsView extends StatelessWidget
|
||||
itemCount: functions.length,
|
||||
padding: const EdgeInsets.only(top: 24.0),
|
||||
itemBuilder: (context, index) {
|
||||
return DefaultContainer(
|
||||
padding: index == 0
|
||||
? const EdgeInsets.only(top: 8)
|
||||
: index == functions.length - 1
|
||||
? const EdgeInsets.only(bottom: 8)
|
||||
: EdgeInsets.zero,
|
||||
margin: EdgeInsets.zero,
|
||||
borderRadius: index == 0
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(20), topRight: Radius.circular(20))
|
||||
: index == functions.length - 1
|
||||
? const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20))
|
||||
: BorderRadius.zero,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||
builder: (context, state) {
|
||||
return SceneListTile(
|
||||
iconsSize: 22,
|
||||
minLeadingWidth: 20,
|
||||
assetPath: functions[index].icon,
|
||||
titleString: functions[index].operationName,
|
||||
trailingWidget: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
if (device.productType!.name.toString() == 'ThreeGang' ||
|
||||
device.productType!.name.toString() == 'TwoGang') {
|
||||
final bool isFirstInPair = index % 2 == 0;
|
||||
final bool isLastInPair =
|
||||
index % 2 == 1 || index == functions.length - 1;
|
||||
final bool isLastItem = index == functions.length - 1;
|
||||
return Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
if (isFirstInPair && index != 0) const SizedBox(height: 16),
|
||||
DefaultContainer(
|
||||
padding: EdgeInsets.only(
|
||||
top: isFirstInPair ? 8 : 0,
|
||||
bottom: isLastInPair ? 8 : 0,
|
||||
),
|
||||
margin: EdgeInsets.zero,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(isFirstInPair ? 20 : 0),
|
||||
topRight: Radius.circular(isFirstInPair ? 20 : 0),
|
||||
bottomLeft: Radius.circular(isLastInPair ? 20 : 0),
|
||||
bottomRight: Radius.circular(isLastInPair ? 20 : 0),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||
builder: (context, state) {
|
||||
return SceneListTile(
|
||||
iconsSize: 22,
|
||||
minLeadingWidth: 20,
|
||||
assetPath: functions[index].icon,
|
||||
titleString: functions[index].operationName,
|
||||
trailingWidget: const Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
if (isAutomation) {
|
||||
_showAutomationDialog(
|
||||
context,
|
||||
functions[index],
|
||||
device,
|
||||
);
|
||||
} else {
|
||||
_showTabToRunDialog(
|
||||
context,
|
||||
functions[index],
|
||||
device,
|
||||
);
|
||||
}
|
||||
onPressed: () {
|
||||
if (isAutomation) {
|
||||
_showAutomationDialog(
|
||||
context, functions[index], device);
|
||||
} else {
|
||||
_showTabToRunDialog(
|
||||
context, functions[index], device);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
if (isFirstInPair && !isLastItem)
|
||||
SizedBox(
|
||||
width: context.width * 0.8,
|
||||
child: const LightDivider(),
|
||||
),
|
||||
],
|
||||
),
|
||||
index != functions.length - 1
|
||||
? SizedBox(
|
||||
width: context.width * 0.8, child: const LightDivider())
|
||||
: const SizedBox(),
|
||||
],
|
||||
),
|
||||
);
|
||||
)
|
||||
]);
|
||||
} else {
|
||||
return DefaultContainer(
|
||||
padding: index == 0
|
||||
? const EdgeInsets.only(top: 8)
|
||||
: index == functions.length - 1
|
||||
? const EdgeInsets.only(bottom: 8)
|
||||
: EdgeInsets.zero,
|
||||
margin: EdgeInsets.zero,
|
||||
borderRadius: index == 0 && index == functions.length - 1
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20),
|
||||
)
|
||||
: index == 0
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
)
|
||||
: index == functions.length - 1
|
||||
? const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20),
|
||||
)
|
||||
: BorderRadius.zero,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||
builder: (context, state) {
|
||||
return SceneListTile(
|
||||
iconsSize: 22,
|
||||
minLeadingWidth: 20,
|
||||
assetPath: functions[index].icon,
|
||||
titleString: functions[index].operationName,
|
||||
trailingWidget: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
if (isAutomation) {
|
||||
_showAutomationDialog(
|
||||
context, functions[index], device);
|
||||
} else {
|
||||
_showTabToRunDialog(
|
||||
context, functions[index], device);
|
||||
}
|
||||
},
|
||||
);
|
||||
}),
|
||||
index != functions.length - 1
|
||||
? SizedBox(
|
||||
width: context.width * 0.8,
|
||||
child: const LightDivider())
|
||||
: const SizedBox(),
|
||||
],
|
||||
));
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@ -20,82 +20,69 @@ class SceneRoomsTabBarDevicesView extends StatefulWidget {
|
||||
_SceneRoomsTabBarDevicesViewState();
|
||||
}
|
||||
|
||||
class _SceneRoomsTabBarDevicesViewState
|
||||
extends State<SceneRoomsTabBarDevicesView>
|
||||
class _SceneRoomsTabBarDevicesViewState extends State<SceneRoomsTabBarDevicesView>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late final TabController _tabController;
|
||||
List<SubSpaceModel>? rooms = [];
|
||||
late final SpaceModel selectedSpace;
|
||||
var rooms = <SubSpaceModel>[];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
selectedSpace = HomeCubit.getInstance().selectedSpace!;
|
||||
selectedSpace = HomeCubit.getInstance().selectedSpace!;
|
||||
|
||||
rooms = List.from(selectedSpace.subspaces ?? []);
|
||||
rooms = List.from(selectedSpace.subspaces);
|
||||
final defaultSubSpaceModel = SubSpaceModel(
|
||||
name: 'All Devices',
|
||||
devices: context.read<DevicesCubit>().allDevices,
|
||||
id: '-1',
|
||||
);
|
||||
|
||||
if (rooms != null && rooms!.isNotEmpty) {
|
||||
if (rooms![0].id != '-1') {
|
||||
rooms?.insert(
|
||||
0,
|
||||
SubSpaceModel(
|
||||
name: 'All Devices',
|
||||
devices: context.read<DevicesCubit>().allDevices,
|
||||
id: '-1',
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
rooms = [
|
||||
SubSpaceModel(
|
||||
name: 'All Devices',
|
||||
devices: context.read<DevicesCubit>().allDevices,
|
||||
id: '-1',
|
||||
)
|
||||
];
|
||||
if (rooms.isNotEmpty) {
|
||||
final isFirstRoomIdValid = rooms[0].id != '-1';
|
||||
if (isFirstRoomIdValid) {
|
||||
rooms.insert(0, defaultSubSpaceModel);
|
||||
}
|
||||
|
||||
_tabController = TabController(length: rooms!.length, vsync: this);
|
||||
_tabController.addListener(_handleTabSwitched);
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
void _handleTabSwitched() {
|
||||
if (_tabController.indexIsChanging) {
|
||||
final value = _tabController.index;
|
||||
|
||||
/// select tab
|
||||
context.read<TabBarBloc>().add(TabChanged(
|
||||
selectedIndex: value,
|
||||
roomId: rooms?[value].id ?? '',
|
||||
unit: selectedSpace));
|
||||
return;
|
||||
} else {
|
||||
rooms = [defaultSubSpaceModel];
|
||||
}
|
||||
|
||||
_tabController = TabController(length: rooms.length, vsync: this);
|
||||
_tabController.addListener(_handleTabSwitched);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_tabController.dispose();
|
||||
_tabController.removeListener(() {});
|
||||
_tabController.dispose();
|
||||
}
|
||||
|
||||
void _handleTabSwitched() {
|
||||
if (_tabController.indexIsChanging) {
|
||||
final index = _tabController.index;
|
||||
|
||||
context.read<TabBarBloc>().add(
|
||||
TabBarTabChangedEvent(
|
||||
selectedIndex: index,
|
||||
roomId: rooms[index].id ?? '',
|
||||
unit: selectedSpace,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: StringsManager.createScene,
|
||||
padding: EdgeInsets.zero,
|
||||
padding: EdgeInsetsDirectional.zero,
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
navigateToRoute(context, Routes.sceneTasksRoute);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.arrow_back_ios,
|
||||
),
|
||||
onPressed: () => navigateToRoute(context, Routes.sceneTasksRoute),
|
||||
icon: const Icon(Icons.arrow_back_ios),
|
||||
),
|
||||
title: StringsManager.createScene,
|
||||
child: SceneDevicesBody(tabController: _tabController, rooms: rooms),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||
@ -8,60 +7,44 @@ import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart'
|
||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart';
|
||||
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/scene_devices/scene_devices_body_tab_bar.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/scene_devices/scene_devices_list.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/app_loading_indicator.dart';
|
||||
|
||||
class SceneDevicesBody extends StatelessWidget {
|
||||
const SceneDevicesBody({
|
||||
super.key,
|
||||
required TabController tabController,
|
||||
required this.tabController,
|
||||
required this.rooms,
|
||||
}) : _tabController = tabController;
|
||||
super.key,
|
||||
});
|
||||
|
||||
final TabController _tabController;
|
||||
final List<SubSpaceModel>? rooms;
|
||||
final TabController tabController;
|
||||
final List<SubSpaceModel> rooms;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isAutomationDeviceStatus =
|
||||
((ModalRoute.of(context)?.settings.arguments as SceneSettingsRouteArguments?)?.sceneType ==
|
||||
CreateSceneEnum.deviceStatusChanges.name);
|
||||
return BlocBuilder<TabBarBloc, TabBarState>(
|
||||
builder: (context, tabState) {
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TabBar(
|
||||
controller: _tabController,
|
||||
dividerColor: Colors.transparent,
|
||||
indicatorColor: Colors.transparent,
|
||||
tabs: [
|
||||
...rooms!.map((e) => Tab(
|
||||
child: BodyLarge(
|
||||
text: e.name ?? '',
|
||||
textAlign: TextAlign.start,
|
||||
style: context.bodyLarge.copyWith(
|
||||
color: (tabState is TabSelected) && tabState.roomId == e.id
|
||||
? ColorsManager.textPrimaryColor
|
||||
: ColorsManager.textPrimaryColor.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
isScrollable: true,
|
||||
tabAlignment: TabAlignment.start,
|
||||
SceneDevicesBodyTabBar(
|
||||
tabController: tabController,
|
||||
rooms: rooms,
|
||||
selectedRoomId: state is TabBarTabSelectedState ? state.roomId : '-1',
|
||||
),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
controller: _tabController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children:
|
||||
rooms!.map((e) => _buildRoomTab(e, context, isAutomationDeviceStatus)).toList(),
|
||||
controller: tabController,
|
||||
children: rooms
|
||||
.map(
|
||||
(room) => _buildRoomTab(
|
||||
room,
|
||||
_isAutomationDeviceStatus(context),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -70,52 +53,46 @@ class SceneDevicesBody extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildRoomTab(SubSpaceModel room, BuildContext context, bool isAutomationDeviceStatus) {
|
||||
bool _isAutomationDeviceStatus(BuildContext context) {
|
||||
final routeArguments =
|
||||
ModalRoute.of(context)?.settings.arguments as SceneSettingsRouteArguments?;
|
||||
final deviceStatusChangesScene = CreateSceneEnum.deviceStatusChanges.name;
|
||||
final sceneType = routeArguments?.sceneType;
|
||||
|
||||
return sceneType == deviceStatusChangesScene;
|
||||
}
|
||||
|
||||
Widget _buildRoomTab(
|
||||
SubSpaceModel room,
|
||||
bool isAutomationDeviceStatus,
|
||||
) {
|
||||
return BlocBuilder<DeviceManagerBloc, DeviceManagerState>(
|
||||
builder: (context, state) {
|
||||
if (state.loading && state.devices == null) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state.devices != null && state.devices!.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
itemCount: state.devices!.length,
|
||||
itemBuilder: (context, index) {
|
||||
final device = state.devices![index];
|
||||
return DefaultContainer(
|
||||
child: SceneListTile(
|
||||
minLeadingWidth: 40,
|
||||
leadingWidget: SvgPicture.asset(device.icon ?? ''),
|
||||
titleWidget: BodyMedium(
|
||||
text: device.name ?? '',
|
||||
style: context.titleSmall.copyWith(
|
||||
color: ColorsManager.secondaryTextColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
trailingWidget: const Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 16,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routes.deviceFunctionsRoute,
|
||||
arguments: {
|
||||
"device": device,
|
||||
"isAutomationDeviceStatus": isAutomationDeviceStatus
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
} else if (state.error != null) {
|
||||
return const Center(child: Text('Something went wrong'));
|
||||
} else {
|
||||
return const SizedBox();
|
||||
}
|
||||
final isLoading = state.loading && state.devices == null;
|
||||
final hasData =
|
||||
state.devices != null && (state.devices?.isNotEmpty ?? false);
|
||||
final hasError = state.error != null;
|
||||
|
||||
final widgets = <bool, Widget>{
|
||||
isLoading: const AppLoadingIndicator(),
|
||||
hasError: Center(child: Text('${state.error}')),
|
||||
hasData: SceneDevicesList(
|
||||
devices: state.devices ?? [],
|
||||
isAutomationDeviceStatus: isAutomationDeviceStatus,
|
||||
),
|
||||
};
|
||||
|
||||
final invalidWidgetEntry = MapEntry(
|
||||
true,
|
||||
Center(child: Text('This subspace has no devices')),
|
||||
);
|
||||
|
||||
final validWidgetEntry = widgets.entries.firstWhere(
|
||||
(entry) => entry.key == true,
|
||||
orElse: () => invalidWidgetEntry,
|
||||
);
|
||||
|
||||
return validWidgetEntry.value;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class SceneDevicesBodyTabBar extends StatelessWidget {
|
||||
const SceneDevicesBodyTabBar({
|
||||
required this.tabController,
|
||||
required this.rooms,
|
||||
required this.selectedRoomId,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String selectedRoomId;
|
||||
|
||||
final TabController tabController;
|
||||
final List<SubSpaceModel> rooms;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TabBar(
|
||||
controller: tabController,
|
||||
dividerColor: Colors.transparent,
|
||||
indicatorColor: Colors.transparent,
|
||||
isScrollable: true,
|
||||
tabAlignment: TabAlignment.start,
|
||||
tabs: rooms.map((e) {
|
||||
final isSelected = selectedRoomId == e.id;
|
||||
return Tab(
|
||||
child: BodyLarge(
|
||||
text: e.name ?? '',
|
||||
textAlign: TextAlign.start,
|
||||
style: context.bodyLarge.copyWith(
|
||||
color: isSelected
|
||||
? ColorsManager.textPrimaryColor
|
||||
: ColorsManager.textPrimaryColor.withValues(
|
||||
alpha: 0.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class SceneDevicesList extends StatelessWidget {
|
||||
const SceneDevicesList({
|
||||
required this.isAutomationDeviceStatus,
|
||||
required this.devices,
|
||||
super.key,
|
||||
});
|
||||
final List<DeviceModel> devices;
|
||||
final bool isAutomationDeviceStatus;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.builder(
|
||||
itemCount: devices.length,
|
||||
itemBuilder: (context, index) => _buildDeviceTile(context, devices[index]),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeviceTile(
|
||||
BuildContext context,
|
||||
DeviceModel device,
|
||||
) {
|
||||
return DefaultContainer(
|
||||
child: SceneListTile(
|
||||
minLeadingWidth: 40,
|
||||
leadingWidget: SvgPicture.asset(device.icon ?? ''),
|
||||
titleWidget: BodyMedium(
|
||||
text: device.name ?? '',
|
||||
style: context.titleSmall.copyWith(
|
||||
color: ColorsManager.secondaryTextColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
trailingWidget: const Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 16,
|
||||
),
|
||||
onPressed: () => _navigateToDeviceFunctions(context, device),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _navigateToDeviceFunctions(
|
||||
BuildContext context,
|
||||
DeviceModel device,
|
||||
) {
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.deviceFunctionsRoute,
|
||||
arguments: {
|
||||
"device": device,
|
||||
"isAutomationDeviceStatus": isAutomationDeviceStatus,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1142,5 +1142,9 @@ class Assets {
|
||||
|
||||
static const String toggleSwitchSmall = 'assets/icons/toggleSwitchSmall.svg';
|
||||
static const String offToggleSwitchSmall = 'assets/icons/offToggleSwitchSmall.svg';
|
||||
static const String saveRoutinesIcon = 'assets/icons/save_routines_icon.svg';
|
||||
static const String cancelIcon = 'assets/icons/cancel_icon.svg';
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -3,8 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
|
||||
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||
import 'package:syncrow_app/features/app_layout/view/app_layout.dart';
|
||||
import 'package:syncrow_app/features/auth/view/otp_view.dart';
|
||||
import 'package:syncrow_app/features/auth/view/login_view.dart';
|
||||
import 'package:syncrow_app/features/auth/view/otp_view.dart';
|
||||
import 'package:syncrow_app/features/auth/view/sign_up_view.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
|
||||
@ -17,11 +17,12 @@ import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart'
|
||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
|
||||
import 'package:syncrow_app/features/scene/view/device_functions_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_auto_settings.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_rooms_tabbar.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/smart_automation_select_route.dart';
|
||||
import 'package:syncrow_app/features/splash/view/splash_view.dart';
|
||||
|
||||
import 'routing_constants.dart';
|
||||
|
||||
class Router {
|
||||
@ -88,7 +89,7 @@ class Router {
|
||||
BlocProvider(
|
||||
create: (BuildContext context) =>
|
||||
TabBarBloc(context.read<DeviceManagerBloc>())
|
||||
..add(TabChanged(
|
||||
..add(TabBarTabChangedEvent(
|
||||
selectedIndex: 0,
|
||||
roomId: '-1',
|
||||
unit: SpaceModel(
|
||||
|
||||
@ -11,7 +11,7 @@ abstract class ApiEndpoints {
|
||||
static const String sendOtp = '/authentication/user/send-otp';
|
||||
static const String verifyOtp = '/authentication/user/verify-otp';
|
||||
static const String forgetPassword = '/authentication/user/forget-password';
|
||||
|
||||
static const String clientLogin = '/client/token';
|
||||
////////////////////////////////////// Spaces ///////////////////////////////////////
|
||||
|
||||
///Community Module
|
||||
@ -111,9 +111,9 @@ abstract class ApiEndpoints {
|
||||
//POST
|
||||
static const String addDeviceToRoom = '/device/room';
|
||||
static const String addDeviceToGroup = '/device/group';
|
||||
static const String controlDevice = '/device/{deviceUuid}/control';
|
||||
static const String controlDevice = '/devices/{deviceUuid}/command';
|
||||
static const String firmwareDevice =
|
||||
'/device/{deviceUuid}/firmware/{firmwareVersion}';
|
||||
'/devices/{deviceUuid}/firmware/{firmwareVersion}';
|
||||
static const String getDevicesByUserId = '/device/user/{userId}';
|
||||
static const String getDevicesByUnitId = '/device/unit/{unitUuid}';
|
||||
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
||||
@ -121,13 +121,13 @@ abstract class ApiEndpoints {
|
||||
//GET
|
||||
static const String deviceByRoom =
|
||||
'/projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices';
|
||||
static const String deviceByUuid = '/device/{deviceUuid}';
|
||||
static const String deviceFunctions = '/device/{deviceUuid}/functions';
|
||||
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
||||
static const String deviceByUuid = '/devices/{deviceUuid}';
|
||||
static const String deviceFunctions = '/devices/{deviceUuid}/functions';
|
||||
static const String gatewayApi = '/devices/gateway/{gatewayUuid}/devices';
|
||||
static const String deviceFunctionsStatus =
|
||||
'/device/{deviceUuid}/functions/status';
|
||||
'/devices/{deviceUuid}/functions/status';
|
||||
static const String powerClamp =
|
||||
'/device/{powerClampUuid}/power-clamp/status';
|
||||
'/devices/{deviceUuid}/functions/status';
|
||||
|
||||
///Device Permission Module
|
||||
//POST
|
||||
@ -153,7 +153,8 @@ abstract class ApiEndpoints {
|
||||
static const String getScene = '/scene/tap-to-run/{sceneId}';
|
||||
static const String getIconScene = '/scene/icon';
|
||||
|
||||
static const String getUnitAutomation = '/projects/{projectId}/communities/{communityId}/spaces/{unitUuid}/automations';
|
||||
static const String getUnitAutomation =
|
||||
'/projects/{projectId}/communities/{communityId}/spaces/{unitUuid}/automations';
|
||||
|
||||
static const String getAutomationDetails =
|
||||
'/projects/{projectId}/automations/{automationId}';
|
||||
@ -161,7 +162,8 @@ abstract class ApiEndpoints {
|
||||
/// PUT
|
||||
static const String updateScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
static const String updateAutomation = '/projects/{projectId}/automations/{automationId}';
|
||||
static const String updateAutomation =
|
||||
'/projects/{projectId}/automations/{automationId}';
|
||||
|
||||
static const String updateAutomationStatus =
|
||||
'/projects/{projectId}/automations/{automationId}';
|
||||
@ -169,7 +171,8 @@ abstract class ApiEndpoints {
|
||||
/// DELETE
|
||||
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
static const String deleteAutomation = '/projects/{projectId}/automations/{automationId}';
|
||||
static const String deleteAutomation =
|
||||
'/projects/{projectId}/automations/{automationId}';
|
||||
|
||||
//////////////////////Door Lock //////////////////////
|
||||
//online
|
||||
@ -213,18 +216,18 @@ abstract class ApiEndpoints {
|
||||
static const String changeSchedule = '/schedule/enable/{deviceUuid}';
|
||||
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
|
||||
static const String reportLogs =
|
||||
'/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
||||
static const String controlBatch = '/device/control/batch';
|
||||
static const String statusBatch = '/device/status/batch';
|
||||
static const String deviceScene = '/device/{deviceUuid}/scenes';
|
||||
'/devices/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
||||
static const String controlBatch = '/devices/batch';
|
||||
static const String statusBatch = '/devices/batch';
|
||||
static const String deviceScene = '/devices/{deviceUuid}/scenes';
|
||||
|
||||
static const String fourSceneByName =
|
||||
'/device/{deviceUuid}/scenes?switchName={switchName}';
|
||||
'/devices/{deviceUuid}/scenes?switchName={switchName}';
|
||||
|
||||
static const String resetDevice = '/factory/reset/{deviceUuid}';
|
||||
static const String unAssignScenesDevice =
|
||||
'/device/{deviceUuid}/scenes?switchName={switchName}';
|
||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
||||
'/devices/{deviceUuid}/scenes?switchName={switchName}';
|
||||
static const String getDeviceLogs = '/devices/report-logs/{uuid}?code={code}';
|
||||
static const String terms = '/terms';
|
||||
static const String policy = '/policy';
|
||||
static const String getPermission = '/permission/{roleUuid}';
|
||||
|
||||
@ -25,11 +25,15 @@ class AuthenticationAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<bool> signUp({required SignUpModel model}) async {
|
||||
static Future<bool> signUp({
|
||||
required SignUpModel model,
|
||||
required String accessToken,
|
||||
}) async {
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.signUp,
|
||||
body: model.toJson(),
|
||||
showServerMessage: false,
|
||||
accessToken: accessToken,
|
||||
expectedResponseModel: (json) => json['statusCode'] == 201);
|
||||
return response;
|
||||
}
|
||||
@ -63,4 +67,20 @@ class AuthenticationAPI {
|
||||
expectedResponseModel: (json) => json['data']);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> fetchClientToken({
|
||||
required String clientId,
|
||||
required String clientSecret,
|
||||
}) async {
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.clientLogin,
|
||||
body: {
|
||||
'clientId': clientId,
|
||||
'clientSecret': clientSecret,
|
||||
},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => json['data'],
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
@ -8,7 +8,8 @@ import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||
import 'package:syncrow_app/services/api/http_service.dart';
|
||||
import 'package:syncrow_app/utils/constants/temp_const.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
import '../../features/devices/model/create_temporary_password_model.dart';
|
||||
|
||||
class DevicesAPI {
|
||||
@ -39,7 +40,7 @@ class DevicesAPI {
|
||||
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
|
||||
body: {"deviceName": deviceName},
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
return json['data'];
|
||||
},
|
||||
);
|
||||
return response;
|
||||
@ -92,7 +93,7 @@ class DevicesAPI {
|
||||
.replaceAll('{deviceUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
return json['data'];
|
||||
},
|
||||
);
|
||||
return response;
|
||||
@ -101,7 +102,7 @@ class DevicesAPI {
|
||||
static Future<Map<String, dynamic>> getPowerClampStatus(
|
||||
String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId),
|
||||
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{powerClampUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -132,7 +133,7 @@ class DevicesAPI {
|
||||
path: ApiEndpoints.deviceFunctions.replaceAll('{deviceUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
final functions = FunctionModel.fromJson(json);
|
||||
final functions = FunctionModel.fromJson(json['data']);
|
||||
return functions;
|
||||
});
|
||||
return response;
|
||||
@ -188,7 +189,7 @@ class DevicesAPI {
|
||||
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
return json['data'];
|
||||
});
|
||||
return response;
|
||||
}
|
||||
@ -264,7 +265,7 @@ class DevicesAPI {
|
||||
if (json == null || json.isEmpty || json == []) {
|
||||
return devices;
|
||||
}
|
||||
for (var device in json['devices']) {
|
||||
for (var device in json['data']['devices']) {
|
||||
devices.add(DeviceModel.fromJson(device));
|
||||
}
|
||||
return devices;
|
||||
@ -491,7 +492,12 @@ class DevicesAPI {
|
||||
}) async {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.controlBatch,
|
||||
body: {"devicesUuid": devicesUuid, "code": code, "value": value},
|
||||
body: {
|
||||
"devicesUuid": devicesUuid,
|
||||
"code": code,
|
||||
"value": value,
|
||||
"operationType": 'COMMAND',
|
||||
},
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -577,7 +583,7 @@ class DevicesAPI {
|
||||
path: path,
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
final data = json['data'];
|
||||
final data = json['data'] as List<dynamic>?;
|
||||
|
||||
if (data == null || data.isEmpty) {
|
||||
return <DeviceModel>[];
|
||||
@ -585,9 +591,14 @@ class DevicesAPI {
|
||||
if (json == null || json.isEmpty || json == []) {
|
||||
return <DeviceModel>[];
|
||||
}
|
||||
return data
|
||||
.map<DeviceModel>((device) => DeviceModel.fromJson(device))
|
||||
.toList();
|
||||
final result = <DeviceModel>[];
|
||||
for (final device in data) {
|
||||
final mappedDevice = DeviceModel.fromJson(device);
|
||||
if (mappedDevice.productType?.name != DeviceType.FlushMountedSensor.name) {
|
||||
result.add(mappedDevice);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ class HomeManagementAPI {
|
||||
path: ApiEndpoints.devices.replaceAll("{projectUuid}", projectUuid),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
json.forEach((value) {
|
||||
json['data'].forEach((value) {
|
||||
list.add(DeviceModel.fromJson(value));
|
||||
});
|
||||
});
|
||||
|
||||
@ -48,13 +48,26 @@ class HTTPService {
|
||||
Options? options,
|
||||
dynamic body,
|
||||
bool showServerMessage = true,
|
||||
String? accessToken,
|
||||
required T Function(dynamic) expectedResponseModel}) async {
|
||||
try {
|
||||
final authOptions = options ??
|
||||
Options(
|
||||
headers: accessToken != null
|
||||
? {
|
||||
'Authorization': 'Bearer $accessToken',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
final response = await client.post(
|
||||
path,
|
||||
data: body,
|
||||
queryParameters: queryParameters,
|
||||
options: options,
|
||||
options: authOptions,
|
||||
);
|
||||
return expectedResponseModel(response.data);
|
||||
} catch (error) {
|
||||
|
||||
@ -62,6 +62,7 @@ enum DeviceType {
|
||||
SixScene,
|
||||
SOS,
|
||||
Other,
|
||||
FlushMountedSensor,
|
||||
}
|
||||
|
||||
enum FunctionType { Boolean, Enum, Integer, Raw, String }
|
||||
@ -96,6 +97,7 @@ Map<String, DeviceType> devicesTypesMap = {
|
||||
"4S": DeviceType.FourScene,
|
||||
"6S": DeviceType.SixScene,
|
||||
"SOS": DeviceType.SOS,
|
||||
"NCPS": DeviceType.FlushMountedSensor,
|
||||
};
|
||||
|
||||
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
|
||||
Reference in New Issue
Block a user