mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
push ac functions and gang switches functions
This commit is contained in:
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"automations"
|
||||
]
|
||||
}
|
@ -4,6 +4,9 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart'
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/three_gang_switch/three_gang_switch.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/two_gang_switch/two_gang_switch.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/enum/device_types.dart';
|
||||
|
||||
@ -71,7 +74,6 @@ class AllDevicesModel {
|
||||
int? batteryLevel;
|
||||
String? productName;
|
||||
List<DeviceSpaceModel>? spaces;
|
||||
List<DeviceFunction>? _deviceFunctions;
|
||||
|
||||
AllDevicesModel({
|
||||
this.room,
|
||||
@ -104,8 +106,12 @@ class AllDevicesModel {
|
||||
this.spaces,
|
||||
});
|
||||
AllDevicesModel.fromJson(Map<String, dynamic> json) {
|
||||
room = (json['room'] != null && (json['room'] is Map)) ? DevicesModelRoom.fromJson(json['room']) : null;
|
||||
unit = (json['unit'] != null && (json['unit'] is Map)) ? DevicesModelUnit.fromJson(json['unit']) : null;
|
||||
room = (json['room'] != null && (json['room'] is Map))
|
||||
? DevicesModelRoom.fromJson(json['room'])
|
||||
: null;
|
||||
unit = (json['unit'] != null && (json['unit'] is Map))
|
||||
? DevicesModelUnit.fromJson(json['unit'])
|
||||
: null;
|
||||
community = (json['community'] != null && (json['community'] is Map))
|
||||
? DeviceCommunityModel.fromJson(json['community'])
|
||||
: null;
|
||||
@ -134,7 +140,9 @@ class AllDevicesModel {
|
||||
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
|
||||
productName = json['productName']?.toString();
|
||||
if (json['spaces'] != null && json['spaces'] is List) {
|
||||
spaces = (json['spaces'] as List).map((space) => DeviceSpaceModel.fromJson(space)).toList();
|
||||
spaces = (json['spaces'] as List)
|
||||
.map((space) => DeviceSpaceModel.fromJson(space))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,7 +190,8 @@ SOS
|
||||
String tempIcon = '';
|
||||
if (type == DeviceType.LightBulb) {
|
||||
tempIcon = Assets.lightBulb;
|
||||
} else if (type == DeviceType.CeilingSensor || type == DeviceType.WallSensor) {
|
||||
} else if (type == DeviceType.CeilingSensor ||
|
||||
type == DeviceType.WallSensor) {
|
||||
tempIcon = Assets.sensors;
|
||||
} else if (type == DeviceType.AC) {
|
||||
tempIcon = Assets.ac;
|
||||
@ -218,11 +227,11 @@ SOS
|
||||
return tempIcon;
|
||||
}
|
||||
|
||||
List<DeviceFunction> get deviceFunctions {
|
||||
_deviceFunctions ??= _getDeviceFunctions();
|
||||
return _deviceFunctions!;
|
||||
List<DeviceFunction> get functions {
|
||||
return _getDeviceFunctions();
|
||||
}
|
||||
|
||||
//! Functions for Devices Types
|
||||
List<DeviceFunction> _getDeviceFunctions() {
|
||||
switch (productType) {
|
||||
case 'AC':
|
||||
@ -234,7 +243,38 @@ SOS
|
||||
ChildLockFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
];
|
||||
|
||||
// other product types
|
||||
case '1G':
|
||||
return [
|
||||
OneGangSwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
OneGangCountdownFunction(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
];
|
||||
|
||||
case '2G':
|
||||
return [
|
||||
TwoGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangCountdown1Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangCountdown2Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
];
|
||||
|
||||
case '3G':
|
||||
return [
|
||||
ThreeGangSwitch1Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangSwitch2Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangSwitch3Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown1Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown2Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown3Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
@ -1,26 +1,63 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
mixin ACHelper {
|
||||
Future<Map<String, dynamic>?> showACFunctionsDialog(BuildContext context, List<DeviceFunction<dynamic>> functions) {
|
||||
class ACHelper {
|
||||
static Future<Map<String, dynamic>?> showACFunctionsDialog(
|
||||
BuildContext context,
|
||||
List<DeviceFunction<dynamic>> functions,
|
||||
) async {
|
||||
List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList();
|
||||
String? selectedFunction;
|
||||
dynamic selectedValue;
|
||||
dynamic selectedValue = 20;
|
||||
String? selectedCondition = "==";
|
||||
List<bool> _selectedConditions = [false, true, false];
|
||||
|
||||
return showDialog(
|
||||
return showDialog<Map<String, dynamic>?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Container(
|
||||
content: _buildDialogContent(
|
||||
context,
|
||||
setState,
|
||||
acFunctions,
|
||||
selectedFunction,
|
||||
selectedValue,
|
||||
selectedCondition,
|
||||
_selectedConditions,
|
||||
(fn) => selectedFunction = fn,
|
||||
(val) => selectedValue = val,
|
||||
(cond) => selectedCondition = cond,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Build dialog content for AC functions dialog
|
||||
static Widget _buildDialogContent(
|
||||
BuildContext context,
|
||||
StateSetter setState,
|
||||
List<ACFunction> acFunctions,
|
||||
String? selectedFunction,
|
||||
dynamic selectedValue,
|
||||
String? selectedCondition,
|
||||
List<bool> selectedConditions,
|
||||
Function(String?) onFunctionSelected,
|
||||
Function(dynamic) onValueSelected,
|
||||
Function(String?) onConditionSelected,
|
||||
) {
|
||||
return Container(
|
||||
width: selectedFunction != null ? 600 : 360,
|
||||
height: 450,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
@ -28,9 +65,50 @@ mixin ACHelper {
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildDialogHeader(context),
|
||||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
_buildFunctionsList(
|
||||
context,
|
||||
setState,
|
||||
acFunctions,
|
||||
selectedFunction,
|
||||
onFunctionSelected,
|
||||
),
|
||||
if (selectedFunction != null)
|
||||
_buildValueSelector(
|
||||
context,
|
||||
setState,
|
||||
selectedFunction,
|
||||
selectedValue,
|
||||
selectedCondition,
|
||||
selectedConditions,
|
||||
onValueSelected,
|
||||
onConditionSelected,
|
||||
acFunctions,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildDialogFooter(
|
||||
context,
|
||||
selectedFunction,
|
||||
selectedValue,
|
||||
selectedCondition,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Build header for AC functions dialog
|
||||
static Widget _buildDialogHeader(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'AC Functions',
|
||||
'AC Condition',
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -44,147 +122,290 @@ mixin ACHelper {
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Build functions list for AC functions dialog
|
||||
static Widget _buildFunctionsList(
|
||||
BuildContext context,
|
||||
StateSetter setState,
|
||||
List<ACFunction> acFunctions,
|
||||
String? selectedFunction,
|
||||
Function(String?) onFunctionSelected,
|
||||
) {
|
||||
return Expanded(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
shrinkWrap: false,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: acFunctions.length,
|
||||
separatorBuilder: (context, index) => Divider(),
|
||||
separatorBuilder: (context, index) => const Divider(
|
||||
color: ColorsManager.dividerColor,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final function = acFunctions[index];
|
||||
return ListTile(
|
||||
leading: Image.asset(function.icon, width: 24, height: 24),
|
||||
title: Text(function.operationName),
|
||||
trailing: Icon(Icons.arrow_forward_ios),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selectedFunction = function.code;
|
||||
selectedValue = null;
|
||||
});
|
||||
},
|
||||
leading: SvgPicture.asset(
|
||||
function.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
function.operationName,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
onTap: () => setState(() => onFunctionSelected(function.code)),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (selectedFunction != null)
|
||||
Container(
|
||||
width: 1,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
if (selectedFunction != null)
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
itemCount: acFunctions
|
||||
.firstWhere((f) => f.code == selectedFunction)
|
||||
.getOperationalValues()
|
||||
.length,
|
||||
separatorBuilder: (context, index) => Divider(),
|
||||
itemBuilder: (context, index) {
|
||||
final operationalValue = acFunctions.firstWhere((f) => f.code == selectedFunction)
|
||||
..getOperationalValues()[index];
|
||||
return ListTile(
|
||||
leading: Image.asset(operationalValue.icon, width: 24, height: 24),
|
||||
title: Text(operationalValue.getOperationalValues()[index].description),
|
||||
trailing: Radio<dynamic>(
|
||||
value: operationalValue.getOperationalValues()[index].value,
|
||||
groupValue: selectedValue,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
selectedValue = value;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Build value selector for AC functions dialog
|
||||
static Widget _buildValueSelector(
|
||||
BuildContext context,
|
||||
StateSetter setState,
|
||||
String selectedFunction,
|
||||
dynamic selectedValue,
|
||||
String? selectedCondition,
|
||||
List<bool> selectedConditions,
|
||||
Function(dynamic) onValueSelected,
|
||||
Function(String?) onConditionSelected,
|
||||
List<ACFunction> acFunctions,
|
||||
) {
|
||||
if (selectedFunction == 'temp_set' || selectedFunction == 'temp_current') {
|
||||
return Expanded(
|
||||
child: _buildTemperatureSelector(
|
||||
context,
|
||||
setState,
|
||||
selectedValue,
|
||||
selectedCondition,
|
||||
selectedConditions,
|
||||
onValueSelected,
|
||||
onConditionSelected,
|
||||
),
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
final selectedFn =
|
||||
acFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final values = selectedFn.getOperationalValues();
|
||||
return Expanded(
|
||||
child: _buildOperationalValuesList(
|
||||
context,
|
||||
setState,
|
||||
values,
|
||||
selectedValue,
|
||||
onValueSelected,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Build temperature selector for AC functions dialog
|
||||
static Widget _buildTemperatureSelector(
|
||||
BuildContext context,
|
||||
StateSetter setState,
|
||||
dynamic selectedValue,
|
||||
String? selectedCondition,
|
||||
List<bool> selectedConditions,
|
||||
Function(dynamic) onValueSelected,
|
||||
Function(String?) onConditionSelected,
|
||||
) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_buildConditionToggle(
|
||||
context,
|
||||
setState,
|
||||
selectedConditions,
|
||||
onConditionSelected,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildTemperatureDisplay(context, selectedValue),
|
||||
const SizedBox(height: 20),
|
||||
_buildTemperatureSlider(
|
||||
context,
|
||||
setState,
|
||||
selectedValue,
|
||||
onValueSelected,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 50,
|
||||
width: 1,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// Handle the confirmation action here
|
||||
Navigator.pop(context, {
|
||||
'function': selectedFunction,
|
||||
'value': selectedValue,
|
||||
);
|
||||
}
|
||||
|
||||
/// Build condition toggle for AC functions dialog
|
||||
static Widget _buildConditionToggle(
|
||||
BuildContext context,
|
||||
StateSetter setState,
|
||||
List<bool> selectedConditions,
|
||||
Function(String?) onConditionSelected,
|
||||
) {
|
||||
return ToggleButtons(
|
||||
onPressed: (int index) {
|
||||
setState(() {
|
||||
for (int i = 0; i < selectedConditions.length; i++) {
|
||||
selectedConditions[i] = i == index;
|
||||
}
|
||||
onConditionSelected(index == 0
|
||||
? "<"
|
||||
: index == 1
|
||||
? "=="
|
||||
: ">");
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
selectedBorderColor: ColorsManager.primaryColorWithOpacity,
|
||||
selectedColor: Colors.white,
|
||||
fillColor: ColorsManager.primaryColorWithOpacity,
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 40.0,
|
||||
minWidth: 40.0,
|
||||
),
|
||||
isSelected: selectedConditions,
|
||||
children: const [Text("<"), Text("="), Text(">")],
|
||||
);
|
||||
}
|
||||
|
||||
/// Build temperature display for AC functions dialog
|
||||
static Widget _buildTemperatureDisplay(
|
||||
BuildContext context, dynamic selectedValue) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
'Confirm',
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
'${selectedValue ?? 20}°C',
|
||||
style: context.textTheme.headlineMedium!.copyWith(
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildTemperatureSlider(
|
||||
BuildContext context,
|
||||
StateSetter setState,
|
||||
dynamic selectedValue,
|
||||
Function(dynamic) onValueSelected,
|
||||
) {
|
||||
final currentValue = selectedValue is int ? selectedValue.toDouble() : 20.0;
|
||||
return Slider(
|
||||
value: currentValue,
|
||||
min: 16,
|
||||
max: 30,
|
||||
divisions: 14,
|
||||
label: '${currentValue.toInt()}°C',
|
||||
onChanged: (value) {
|
||||
setState(() => onValueSelected(value.toInt()));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildOperationalValuesList(
|
||||
BuildContext context,
|
||||
StateSetter setState,
|
||||
List<dynamic> values,
|
||||
dynamic selectedValue,
|
||||
Function(dynamic) onValueSelected,
|
||||
) {
|
||||
return ListView.builder(
|
||||
shrinkWrap: false,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: values.length,
|
||||
itemBuilder: (context, index) {
|
||||
final value = values[index];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
value.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
value.description,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Radio<dynamic>(
|
||||
value: value.value,
|
||||
groupValue: selectedValue,
|
||||
onChanged: (newValue) {
|
||||
setState(() => onValueSelected(newValue));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void handleACDeviceDrop(BuildContext context, Map<String, dynamic> data) {
|
||||
final device = data['device'] as AllDevicesModel;
|
||||
final acFunctions = device.deviceFunctions;
|
||||
|
||||
showACFunctionsDialog(context, acFunctions).then((result) {
|
||||
if (result != null) {
|
||||
_addACDeviceToRoutine(context, data, result);
|
||||
}
|
||||
});
|
||||
static Widget _buildDialogFooter(
|
||||
BuildContext context,
|
||||
String? selectedFunction,
|
||||
dynamic selectedValue,
|
||||
String? selectedCondition,
|
||||
) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_buildFooterButton(
|
||||
context,
|
||||
'Cancel',
|
||||
selectedFunction != null ? 299 : 179,
|
||||
() => Navigator.pop(context),
|
||||
),
|
||||
_buildFooterButton(
|
||||
context,
|
||||
'Confirm',
|
||||
selectedFunction != null ? 299 : 179,
|
||||
selectedFunction != null && selectedValue != null
|
||||
? () => Navigator.pop(context, {
|
||||
'function': selectedFunction,
|
||||
'value': selectedValue,
|
||||
'condition': selectedCondition ?? "==",
|
||||
})
|
||||
: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void handleNonACDeviceDrop(BuildContext context, Map<String, dynamic> data) {
|
||||
context.read<RoutineBloc>().add(AddToThenContainer(data));
|
||||
}
|
||||
|
||||
void _addACDeviceToRoutine(BuildContext context, Map<String, dynamic> deviceData, Map<String, dynamic> functionData) {
|
||||
final updatedData = {
|
||||
...deviceData,
|
||||
'function': functionData['function'],
|
||||
'value': functionData['value'],
|
||||
};
|
||||
|
||||
context.read<RoutineBloc>().add(AddToThenContainer(updatedData));
|
||||
|
||||
_logACFunctionSelection(functionData);
|
||||
}
|
||||
|
||||
void _logACFunctionSelection(Map<String, dynamic> functionData) {
|
||||
print('Selected AC function: ${functionData['function']}, Value: ${functionData['value']}');
|
||||
static Widget _buildFooterButton(
|
||||
BuildContext context,
|
||||
String text,
|
||||
double width,
|
||||
VoidCallback? onTap,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: SizedBox(
|
||||
height: 50,
|
||||
width: width,
|
||||
child: Center(
|
||||
child: Text(
|
||||
text,
|
||||
style: context.textTheme.bodyMedium!.copyWith(
|
||||
color: onTap != null
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: ColorsManager.textGray,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/ac_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/one_gang_switch_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/three_gang_switch_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/two_gang_switch_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
|
||||
class DeviceDialogHelper {
|
||||
static Future<Map<String, dynamic>?> showDeviceDialog(
|
||||
BuildContext context,
|
||||
Map<String, dynamic> data,
|
||||
) async {
|
||||
final functions = data['functions'] as List<DeviceFunction>;
|
||||
|
||||
try {
|
||||
final result = await _getDialogForDeviceType(
|
||||
context,
|
||||
data['productType'],
|
||||
functions,
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
return {...data, ...result};
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error: $e');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>?> _getDialogForDeviceType(
|
||||
BuildContext context,
|
||||
String productType,
|
||||
List<DeviceFunction> functions,
|
||||
) async {
|
||||
switch (productType) {
|
||||
case 'AC':
|
||||
return ACHelper.showACFunctionsDialog(context, functions);
|
||||
case '1G':
|
||||
return OneGangSwitchHelper.showSwitchFunctionsDialog(
|
||||
context, functions);
|
||||
case '2G':
|
||||
return TwoGangSwitchHelper.showSwitchFunctionsDialog(
|
||||
context, functions);
|
||||
case '3G':
|
||||
return ThreeGangSwitchHelper.showSwitchFunctionsDialog(
|
||||
context, functions);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
206
lib/pages/routiens/helper/one_gang_switch_helper.dart
Normal file
206
lib/pages/routiens/helper/one_gang_switch_helper.dart
Normal file
@ -0,0 +1,206 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class OneGangSwitchHelper {
|
||||
static Future<Map<String, dynamic>?> showSwitchFunctionsDialog(
|
||||
BuildContext context, List<DeviceFunction<dynamic>> functions) async {
|
||||
List<DeviceFunction<dynamic>> switchFunctions = functions
|
||||
.where(
|
||||
(f) => f is OneGangSwitchFunction || f is OneGangCountdownFunction)
|
||||
.toList();
|
||||
String? selectedFunction;
|
||||
dynamic selectedValue;
|
||||
|
||||
return showDialog<Map<String, dynamic>?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Container(
|
||||
width: selectedFunction != null ? 600 : 360,
|
||||
height: 450,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'1 Gang Light Switch Condition',
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 15, horizontal: 50),
|
||||
child: Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: false,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: switchFunctions.length,
|
||||
separatorBuilder: (context, index) =>
|
||||
const Divider(
|
||||
color: ColorsManager.dividerColor,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final function = switchFunctions[index];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
function.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
function.operationName,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selectedFunction = function.code;
|
||||
selectedValue = null;
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (selectedFunction != null)
|
||||
Expanded(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final selectedFn = switchFunctions.firstWhere(
|
||||
(f) => f.code == selectedFunction)
|
||||
as BaseSwitchFunction;
|
||||
final values =
|
||||
selectedFn.getOperationalValues();
|
||||
return ListView.builder(
|
||||
shrinkWrap: false,
|
||||
physics:
|
||||
const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: values.length,
|
||||
itemBuilder: (context, index) {
|
||||
final value = values[index];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
value.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
value.description,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Radio<dynamic>(
|
||||
value: value.value,
|
||||
groupValue: selectedValue,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
selectedValue = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: selectedFunction != null ? 299 : 179,
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
right:
|
||||
BorderSide(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (selectedFunction != null &&
|
||||
selectedValue != null) {
|
||||
Navigator.pop(context, {
|
||||
'function': selectedFunction,
|
||||
'value': selectedValue,
|
||||
});
|
||||
}
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 50,
|
||||
width: selectedFunction != null ? 299 : 179,
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Confirm',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
211
lib/pages/routiens/helper/three_gang_switch_helper.dart
Normal file
211
lib/pages/routiens/helper/three_gang_switch_helper.dart
Normal file
@ -0,0 +1,211 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/three_gang_switch/three_gang_switch.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class ThreeGangSwitchHelper {
|
||||
static Future<Map<String, dynamic>?> showSwitchFunctionsDialog(
|
||||
BuildContext context, List<DeviceFunction<dynamic>> functions) async {
|
||||
List<DeviceFunction<dynamic>> switchFunctions = functions
|
||||
.where((f) =>
|
||||
f is ThreeGangSwitch1Function ||
|
||||
f is ThreeGangSwitch2Function ||
|
||||
f is ThreeGangSwitch3Function ||
|
||||
f is ThreeGangCountdown1Function ||
|
||||
f is ThreeGangCountdown2Function ||
|
||||
f is ThreeGangCountdown3Function)
|
||||
.toList();
|
||||
String? selectedFunction;
|
||||
dynamic selectedValue;
|
||||
|
||||
return showDialog<Map<String, dynamic>?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Container(
|
||||
width: selectedFunction != null ? 600 : 360,
|
||||
height: 450,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'3 Gangs Light Switch Condition',
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 15, horizontal: 50),
|
||||
child: Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: false,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: switchFunctions.length,
|
||||
separatorBuilder: (context, index) =>
|
||||
const Divider(
|
||||
color: ColorsManager.dividerColor,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final function = switchFunctions[index];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
function.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
function.operationName,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selectedFunction = function.code;
|
||||
selectedValue = null;
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (selectedFunction != null)
|
||||
Expanded(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final selectedFn = switchFunctions.firstWhere(
|
||||
(f) => f.code == selectedFunction)
|
||||
as BaseSwitchFunction;
|
||||
final values =
|
||||
selectedFn.getOperationalValues();
|
||||
return ListView.builder(
|
||||
shrinkWrap: false,
|
||||
physics:
|
||||
const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: values.length,
|
||||
itemBuilder: (context, index) {
|
||||
final value = values[index];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
value.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
value.description,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Radio<dynamic>(
|
||||
value: value.value,
|
||||
groupValue: selectedValue,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
selectedValue = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: selectedFunction != null ? 299 : 179,
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
right:
|
||||
BorderSide(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (selectedFunction != null &&
|
||||
selectedValue != null) {
|
||||
Navigator.pop(context, {
|
||||
'function': selectedFunction,
|
||||
'value': selectedValue,
|
||||
});
|
||||
}
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 50,
|
||||
width: selectedFunction != null ? 299 : 179,
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Confirm',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
209
lib/pages/routiens/helper/two_gang_switch_helper.dart
Normal file
209
lib/pages/routiens/helper/two_gang_switch_helper.dart
Normal file
@ -0,0 +1,209 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/two_gang_switch/two_gang_switch.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class TwoGangSwitchHelper {
|
||||
static Future<Map<String, dynamic>?> showSwitchFunctionsDialog(
|
||||
BuildContext context, List<DeviceFunction<dynamic>> functions) async {
|
||||
List<DeviceFunction<dynamic>> switchFunctions = functions
|
||||
.where((f) =>
|
||||
f is TwoGangSwitch1Function ||
|
||||
f is TwoGangSwitch2Function ||
|
||||
f is TwoGangCountdown1Function ||
|
||||
f is TwoGangCountdown2Function)
|
||||
.toList();
|
||||
String? selectedFunction;
|
||||
dynamic selectedValue;
|
||||
|
||||
return showDialog<Map<String, dynamic>?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Container(
|
||||
width: selectedFunction != null ? 600 : 360,
|
||||
height: 450,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'2 Gangs Light Switch Condition',
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 15, horizontal: 50),
|
||||
child: Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: false,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: switchFunctions.length,
|
||||
separatorBuilder: (context, index) =>
|
||||
const Divider(
|
||||
color: ColorsManager.dividerColor,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final function = switchFunctions[index];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
function.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
function.operationName,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selectedFunction = function.code;
|
||||
selectedValue = null;
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (selectedFunction != null)
|
||||
Expanded(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final selectedFn = switchFunctions.firstWhere(
|
||||
(f) => f.code == selectedFunction)
|
||||
as BaseSwitchFunction;
|
||||
final values =
|
||||
selectedFn.getOperationalValues();
|
||||
return ListView.builder(
|
||||
shrinkWrap: false,
|
||||
physics:
|
||||
const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: values.length,
|
||||
itemBuilder: (context, index) {
|
||||
final value = values[index];
|
||||
return ListTile(
|
||||
leading: SvgPicture.asset(
|
||||
value.icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
title: Text(
|
||||
value.description,
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Radio<dynamic>(
|
||||
value: value.value,
|
||||
groupValue: selectedValue,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
selectedValue = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
width: selectedFunction != null ? 299 : 179,
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
right:
|
||||
BorderSide(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (selectedFunction != null &&
|
||||
selectedValue != null) {
|
||||
Navigator.pop(context, {
|
||||
'function': selectedFunction,
|
||||
'value': selectedValue,
|
||||
});
|
||||
}
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 50,
|
||||
width: selectedFunction != null ? 299 : 179,
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Confirm',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
|
||||
abstract class BaseSwitchFunction extends DeviceFunction<bool> {
|
||||
BaseSwitchFunction({
|
||||
required super.deviceId,
|
||||
required super.deviceName,
|
||||
required super.code,
|
||||
required super.operationName,
|
||||
required super.icon,
|
||||
});
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue);
|
||||
|
||||
List<SwitchOperationalValue> getOperationalValues();
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class OneGangSwitchFunction extends BaseSwitchFunction {
|
||||
OneGangSwitchFunction({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'switch_1',
|
||||
operationName: 'Light Switch',
|
||||
icon: Assets.assetsAcPower,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPower,
|
||||
description: "ON",
|
||||
value: true,
|
||||
),
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF,
|
||||
description: "OFF",
|
||||
value: false,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class OneGangCountdownFunction extends BaseSwitchFunction {
|
||||
OneGangCountdownFunction({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_1',
|
||||
operationName: 'Light Countdown',
|
||||
icon: Assets.assetsLightCountdown,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
];
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
class SwitchOperationalValue {
|
||||
final String icon;
|
||||
final String description;
|
||||
final dynamic value;
|
||||
final double? minValue;
|
||||
final double? maxValue;
|
||||
final double? stepValue;
|
||||
|
||||
SwitchOperationalValue({
|
||||
required this.icon,
|
||||
required this.value,
|
||||
this.description = '',
|
||||
this.minValue,
|
||||
this.maxValue,
|
||||
this.stepValue,
|
||||
});
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class ThreeGangSwitch1Function extends BaseSwitchFunction {
|
||||
ThreeGangSwitch1Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'switch_1',
|
||||
operationName: 'Light 1 Switch',
|
||||
icon: Assets.assetsAcPower,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPower,
|
||||
description: "ON",
|
||||
value: true,
|
||||
),
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF,
|
||||
description: "OFF",
|
||||
value: false,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class ThreeGangCountdown1Function extends BaseSwitchFunction {
|
||||
ThreeGangCountdown1Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_1',
|
||||
operationName: 'Light 1 Countdown',
|
||||
icon: Assets.assetsLightCountdown,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class ThreeGangSwitch2Function extends BaseSwitchFunction {
|
||||
ThreeGangSwitch2Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'switch_2',
|
||||
operationName: 'Light 2 Switch',
|
||||
icon: Assets.assetsAcPower,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPower,
|
||||
description: "ON",
|
||||
value: true,
|
||||
),
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF,
|
||||
description: "OFF",
|
||||
value: false,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class ThreeGangCountdown2Function extends BaseSwitchFunction {
|
||||
ThreeGangCountdown2Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_2',
|
||||
operationName: 'Light 2 Countdown',
|
||||
icon: Assets.assetsLightCountdown,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class ThreeGangSwitch3Function extends BaseSwitchFunction {
|
||||
ThreeGangSwitch3Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'switch_3',
|
||||
operationName: 'Light 3 Switch',
|
||||
icon: Assets.assetsAcPower,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPower,
|
||||
description: "ON",
|
||||
value: true,
|
||||
),
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF,
|
||||
description: "OFF",
|
||||
value: false,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class ThreeGangCountdown3Function extends BaseSwitchFunction {
|
||||
ThreeGangCountdown3Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_3',
|
||||
operationName: 'Light 3 Countdown',
|
||||
icon: Assets.assetsLightCountdown,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
];
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class TwoGangSwitch1Function extends BaseSwitchFunction {
|
||||
TwoGangSwitch1Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'switch_1',
|
||||
operationName: 'Light 1 Switch',
|
||||
icon: Assets.assetsAcPower,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPower,
|
||||
description: "ON",
|
||||
value: true,
|
||||
),
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF,
|
||||
description: "OFF",
|
||||
value: false,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class TwoGangSwitch2Function extends BaseSwitchFunction {
|
||||
TwoGangSwitch2Function({required String deviceId, required String deviceName})
|
||||
: super(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
code: 'switch_2',
|
||||
operationName: 'Light 2 Switch',
|
||||
icon: Assets.assetsAcPower,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPower,
|
||||
description: "ON",
|
||||
value: true,
|
||||
),
|
||||
SwitchOperationalValue(
|
||||
icon: Assets.assetsAcPowerOFF,
|
||||
description: "OFF",
|
||||
value: false,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class TwoGangCountdown1Function extends BaseSwitchFunction {
|
||||
TwoGangCountdown1Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_1',
|
||||
operationName: 'Light 1 Countdown',
|
||||
icon: Assets.assetsLightCountdown,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class TwoGangCountdown2Function extends BaseSwitchFunction {
|
||||
TwoGangCountdown2Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_2',
|
||||
operationName: 'Light 2 Countdown',
|
||||
icon: Assets.assetsLightCountdown,
|
||||
);
|
||||
|
||||
@override
|
||||
bool execute(bool currentStatus, dynamic newValue) {
|
||||
return newValue as bool;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SwitchOperationalValue> getOperationalValues() => [
|
||||
SwitchOperationalValue(
|
||||
icon: '',
|
||||
description: "sec",
|
||||
value: 0.0,
|
||||
minValue: 0,
|
||||
maxValue: 43200,
|
||||
stepValue: 1,
|
||||
),
|
||||
];
|
||||
}
|
@ -11,6 +11,7 @@ class DraggableCard extends StatelessWidget {
|
||||
this.titleColor,
|
||||
this.isDragged = false,
|
||||
this.isDisabled = false,
|
||||
this.deviceData,
|
||||
});
|
||||
|
||||
final String imagePath;
|
||||
@ -18,11 +19,17 @@ class DraggableCard extends StatelessWidget {
|
||||
final Color? titleColor;
|
||||
final bool isDragged;
|
||||
final bool isDisabled;
|
||||
final Map<String, dynamic>? deviceData;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget card = Draggable<Map<String, String>>(
|
||||
data: {'key': UniqueKey().toString(), 'imagePath': imagePath, 'title': title},
|
||||
Widget card = Draggable<Map<String, dynamic>>(
|
||||
data: deviceData ??
|
||||
{
|
||||
'key': UniqueKey().toString(),
|
||||
'imagePath': imagePath,
|
||||
'title': title,
|
||||
},
|
||||
feedback: Transform.rotate(
|
||||
angle: -0.1,
|
||||
child: _buildCardContent(context),
|
||||
|
@ -1,18 +1,17 @@
|
||||
// lib/pages/routiens/widgets/if_container.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
|
||||
class IfContainer extends StatelessWidget {
|
||||
const IfContainer({Key? key}) : super(key: key);
|
||||
const IfContainer({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
return DragTarget<Map<String, String>>(
|
||||
return DragTarget<Map<String, dynamic>>(
|
||||
builder: (context, candidateData, rejectedData) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
@ -20,7 +19,9 @@ class IfContainer extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('IF', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const Text('IF',
|
||||
style:
|
||||
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
@ -37,8 +38,16 @@ class IfContainer extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
},
|
||||
onAccept: (data) {
|
||||
onWillAccept: (data) => data != null,
|
||||
onAccept: (data) async {
|
||||
final result =
|
||||
await DeviceDialogHelper.showDeviceDialog(context, data);
|
||||
if (result != null) {
|
||||
context.read<RoutineBloc>().add(AddToIfContainer(result));
|
||||
} else if (!['AC', '1G', '2G', '3G']
|
||||
.contains(data['productType'])) {
|
||||
context.read<RoutineBloc>().add(AddToIfContainer(data));
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -29,11 +29,18 @@ class RoutineDevices extends StatelessWidget {
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: deviceList.asMap().entries.map((entry) {
|
||||
final index = entry.key;
|
||||
final device = entry.value;
|
||||
return DraggableCard(
|
||||
imagePath: device.getDefaultIcon(device.productType),
|
||||
title: device.name ?? '',
|
||||
deviceData: {
|
||||
'key': UniqueKey().toString(),
|
||||
'imagePath': device.getDefaultIcon(device.productType),
|
||||
'title': device.name ?? '',
|
||||
'deviceId': device.uuid,
|
||||
'productType': device.productType,
|
||||
'functions': device.functions,
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
|
@ -14,10 +14,10 @@ class ScenesAndAutomations extends StatelessWidget {
|
||||
return BlocProvider(
|
||||
create: (context) => RoutineBloc()
|
||||
..add(
|
||||
LoadScenes(spaceId),
|
||||
const LoadScenes(spaceId),
|
||||
)
|
||||
..add(
|
||||
LoadAutomation(spaceId),
|
||||
const LoadAutomation(spaceId),
|
||||
),
|
||||
child: BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
@ -27,11 +27,10 @@ class ScenesAndAutomations extends StatelessWidget {
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: scenes.asMap().entries.map((entry) {
|
||||
final index = entry.key;
|
||||
final scene = entry.value;
|
||||
return DraggableCard(
|
||||
imagePath: Assets.logo,
|
||||
title: scene.name ?? '',
|
||||
title: scene.name,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
|
@ -3,16 +3,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
|
||||
class ThenContainer extends StatelessWidget {
|
||||
const ThenContainer({Key? key}) : super(key: key);
|
||||
const ThenContainer({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
return DragTarget<Map<String, String>>(
|
||||
return DragTarget<Map<String, dynamic>>(
|
||||
builder: (context, candidateData, rejectedData) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@ -20,7 +21,9 @@ class ThenContainer extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('THEN', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const Text('THEN',
|
||||
style:
|
||||
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
@ -37,8 +40,16 @@ class ThenContainer extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
},
|
||||
onAccept: (data) {
|
||||
onWillAccept: (data) => data != null,
|
||||
onAccept: (data) async {
|
||||
final result =
|
||||
await DeviceDialogHelper.showDeviceDialog(context, data);
|
||||
if (result != null) {
|
||||
context.read<RoutineBloc>().add(AddToThenContainer(result));
|
||||
} else if (!['AC', '1G', '2G', '3G']
|
||||
.contains(data['productType'])) {
|
||||
context.read<RoutineBloc>().add(AddToThenContainer(data));
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
|
95
macos/DerivedData/Runner/Logs/Build/.dat.nosync1585.W9c579
Normal file
95
macos/DerivedData/Runner/Logs/Build/.dat.nosync1585.W9c579
Normal file
@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>logFormatVersion</key>
|
||||
<integer>11</integer>
|
||||
<key>logs</key>
|
||||
<dict>
|
||||
<key>DEC061F9-9521-4D0C-959C-43A07F62CC12</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
<string>IDECommandLineBuildLog</string>
|
||||
<key>documentTypeString</key>
|
||||
<string><nil></string>
|
||||
<key>domainType</key>
|
||||
<string>Xcode.IDEActivityLogDomainType.BuildLog</string>
|
||||
<key>fileName</key>
|
||||
<string>DEC061F9-9521-4D0C-959C-43A07F62CC12.xcactivitylog</string>
|
||||
<key>hasPrimaryLog</key>
|
||||
<true/>
|
||||
<key>primaryObservable</key>
|
||||
<dict>
|
||||
<key>highLevelStatus</key>
|
||||
<string>S</string>
|
||||
<key>totalNumberOfAnalyzerIssues</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfErrors</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfTestFailures</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfWarnings</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>schemeIdentifier-containerName</key>
|
||||
<string>Runner project</string>
|
||||
<key>schemeIdentifier-schemeName</key>
|
||||
<string>Flutter Assemble</string>
|
||||
<key>schemeIdentifier-sharedScheme</key>
|
||||
<integer>1</integer>
|
||||
<key>signature</key>
|
||||
<string>Cleaning workspace Runner with scheme Flutter Assemble</string>
|
||||
<key>timeStartedRecording</key>
|
||||
<real>752000674.27645695</real>
|
||||
<key>timeStoppedRecording</key>
|
||||
<real>752000674.42918503</real>
|
||||
<key>title</key>
|
||||
<string>Cleaning workspace Runner with scheme Flutter Assemble</string>
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>DEC061F9-9521-4D0C-959C-43A07F62CC12</string>
|
||||
</dict>
|
||||
<key>FB42CDDD-C79D-4D4B-891A-12C476DFCB10</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
<string>IDECommandLineBuildLog</string>
|
||||
<key>documentTypeString</key>
|
||||
<string><nil></string>
|
||||
<key>domainType</key>
|
||||
<string>Xcode.IDEActivityLogDomainType.BuildLog</string>
|
||||
<key>fileName</key>
|
||||
<string>FB42CDDD-C79D-4D4B-891A-12C476DFCB10.xcactivitylog</string>
|
||||
<key>hasPrimaryLog</key>
|
||||
<true/>
|
||||
<key>primaryObservable</key>
|
||||
<dict>
|
||||
<key>highLevelStatus</key>
|
||||
<string>S</string>
|
||||
<key>totalNumberOfAnalyzerIssues</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfErrors</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfTestFailures</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfWarnings</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>schemeIdentifier-containerName</key>
|
||||
<string>Runner project</string>
|
||||
<key>schemeIdentifier-schemeName</key>
|
||||
<string>Runner</string>
|
||||
<key>schemeIdentifier-sharedScheme</key>
|
||||
<integer>1</integer>
|
||||
<key>signature</key>
|
||||
<string>Cleaning workspace Runner with scheme Runner</string>
|
||||
<key>timeStartedRecording</key>
|
||||
<real>752000674.90370798</real>
|
||||
<key>timeStoppedRecording</key>
|
||||
<real>752000675.05962098</real>
|
||||
<key>title</key>
|
||||
<string>Cleaning workspace Runner with scheme Runner</string>
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>FB42CDDD-C79D-4D4B-891A-12C476DFCB10</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
Binary file not shown.
53
macos/DerivedData/Runner/Logs/Build/LogStoreManifest.plist
Normal file
53
macos/DerivedData/Runner/Logs/Build/LogStoreManifest.plist
Normal file
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>logFormatVersion</key>
|
||||
<integer>11</integer>
|
||||
<key>logs</key>
|
||||
<dict>
|
||||
<key>DEC061F9-9521-4D0C-959C-43A07F62CC12</key>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
<string>IDECommandLineBuildLog</string>
|
||||
<key>documentTypeString</key>
|
||||
<string><nil></string>
|
||||
<key>domainType</key>
|
||||
<string>Xcode.IDEActivityLogDomainType.BuildLog</string>
|
||||
<key>fileName</key>
|
||||
<string>DEC061F9-9521-4D0C-959C-43A07F62CC12.xcactivitylog</string>
|
||||
<key>hasPrimaryLog</key>
|
||||
<true/>
|
||||
<key>primaryObservable</key>
|
||||
<dict>
|
||||
<key>highLevelStatus</key>
|
||||
<string>S</string>
|
||||
<key>totalNumberOfAnalyzerIssues</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfErrors</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfTestFailures</key>
|
||||
<integer>0</integer>
|
||||
<key>totalNumberOfWarnings</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>schemeIdentifier-containerName</key>
|
||||
<string>Runner project</string>
|
||||
<key>schemeIdentifier-schemeName</key>
|
||||
<string>Flutter Assemble</string>
|
||||
<key>schemeIdentifier-sharedScheme</key>
|
||||
<integer>1</integer>
|
||||
<key>signature</key>
|
||||
<string>Cleaning workspace Runner with scheme Flutter Assemble</string>
|
||||
<key>timeStartedRecording</key>
|
||||
<real>752000674.27645695</real>
|
||||
<key>timeStoppedRecording</key>
|
||||
<real>752000674.42918503</real>
|
||||
<key>title</key>
|
||||
<string>Cleaning workspace Runner with scheme Flutter Assemble</string>
|
||||
<key>uniqueIdentifier</key>
|
||||
<string>DEC061F9-9521-4D0C-959C-43A07F62CC12</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
10
macos/DerivedData/Runner/Logs/Launch/LogStoreManifest.plist
Normal file
10
macos/DerivedData/Runner/Logs/Launch/LogStoreManifest.plist
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>logFormatVersion</key>
|
||||
<integer>11</integer>
|
||||
<key>logs</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>logFormatVersion</key>
|
||||
<integer>11</integer>
|
||||
<key>logs</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
</plist>
|
10
macos/DerivedData/Runner/Logs/Package/LogStoreManifest.plist
Normal file
10
macos/DerivedData/Runner/Logs/Package/LogStoreManifest.plist
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>logFormatVersion</key>
|
||||
<integer>11</integer>
|
||||
<key>logs</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
</plist>
|
10
macos/DerivedData/Runner/Logs/Test/LogStoreManifest.plist
Normal file
10
macos/DerivedData/Runner/Logs/Test/LogStoreManifest.plist
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>logFormatVersion</key>
|
||||
<integer>11</integer>
|
||||
<key>logs</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
</plist>
|
10
macos/DerivedData/Runner/info.plist
Normal file
10
macos/DerivedData/Runner/info.plist
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LastAccessedDate</key>
|
||||
<date>2024-10-30T17:04:35Z</date>
|
||||
<key>WorkspacePath</key>
|
||||
<string>/Users/akmz/Developer/web/syncrow-web/web/macos/Runner.xcworkspace</string>
|
||||
</dict>
|
||||
</plist>
|
@ -76,6 +76,7 @@ flutter:
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
assets:
|
||||
- assets/icons/automation_functions/
|
||||
- assets/icons/functions_icons/
|
||||
- assets/icons/routine/
|
||||
- assets/icons/
|
||||
- assets/images/
|
||||
|
Reference in New Issue
Block a user