Bug fixes

This commit is contained in:
Abdullah Alassaf
2024-12-02 03:58:31 +03:00
parent 1aa6b78fb4
commit ff4ce8ed01
14 changed files with 295 additions and 452 deletions

View File

@ -1,28 +0,0 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'switch_tabs_event.dart';
part 'switch_tabs_state.dart';
class SwitchTabsBloc extends Bloc<SwitchTabsEvent, SwitchTabsState> {
SwitchTabsBloc() : super(SwitchTabsInitial()) {
on<TriggerSwitchTabsEvent>(_switchTab);
on<CreateNewRoutineViewEvent>(_newRoutineView);
}
FutureOr<void> _switchTab(
TriggerSwitchTabsEvent event,
Emitter<SwitchTabsState> emit,
) {
emit(SelectedTabState(event.isRoutineView));
}
FutureOr<void> _newRoutineView(
CreateNewRoutineViewEvent event,
Emitter<SwitchTabsState> emit,
) {
emit(ShowCreateRoutineState(event.showCreateNewRoutineView));
}
}

View File

@ -1,21 +0,0 @@
part of 'switch_tabs_bloc.dart';
sealed class SwitchTabsEvent extends Equatable {
const SwitchTabsEvent();
}
class TriggerSwitchTabsEvent extends SwitchTabsEvent {
final bool isRoutineView;
const TriggerSwitchTabsEvent(this.isRoutineView);
@override
List<Object?> get props => [isRoutineView];
}
class CreateNewRoutineViewEvent extends SwitchTabsEvent {
final bool showCreateNewRoutineView;
const CreateNewRoutineViewEvent(this.showCreateNewRoutineView);
@override
List<Object?> get props => [showCreateNewRoutineView];
}

View File

@ -1,26 +0,0 @@
part of 'switch_tabs_bloc.dart';
sealed class SwitchTabsState extends Equatable {
const SwitchTabsState();
}
final class SwitchTabsInitial extends SwitchTabsState {
@override
List<Object> get props => [];
}
class SelectedTabState extends SwitchTabsState {
final bool selectedTab;
const SelectedTabState(this.selectedTab);
@override
List<Object?> get props => [selectedTab];
}
class ShowCreateRoutineState extends SwitchTabsState {
final bool showCreateRoutine;
const ShowCreateRoutineState(this.showCreateRoutine);
@override
List<Object?> get props => [showCreateRoutine];
}

View File

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_managment_body.dart';
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.dart';
import 'package:syncrow_web/pages/routiens/view/routines_view.dart';
import 'package:syncrow_web/utils/color_manager.dart';
@ -18,10 +18,6 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) =>
SwitchTabsBloc()..add(const TriggerSwitchTabsEvent(false)),
),
BlocProvider(
create: (context) => DeviceManagementBloc()..add(FetchDevices()),
),
@ -33,8 +29,7 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
style: Theme.of(context).textTheme.headlineLarge,
),
),
centerBody: BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
builder: (context, state) {
centerBody: BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
@ -44,20 +39,14 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
),
onPressed: () {
context
.read<SwitchTabsBloc>()
.add(const TriggerSwitchTabsEvent(false));
.read<RoutineBloc>()
.add(const TriggerSwitchTabsEvent(isRoutineTab: false));
},
child: Text(
'Devices',
style: context.textTheme.titleMedium?.copyWith(
color:
state is SelectedTabState && state.selectedTab == false
? ColorsManager.whiteColors
: ColorsManager.grayColor,
fontWeight: (state is SelectedTabState) &&
state.selectedTab == false
? FontWeight.w700
: FontWeight.w400,
color: !state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor,
fontWeight: !state.routineTab ? FontWeight.w700 : FontWeight.w400,
),
),
),
@ -66,21 +55,13 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
backgroundColor: null,
),
onPressed: () {
context
.read<SwitchTabsBloc>()
.add(const TriggerSwitchTabsEvent(true));
context.read<RoutineBloc>().add(const TriggerSwitchTabsEvent(isRoutineTab: true));
},
child: Text(
'Routines',
style: context.textTheme.titleMedium?.copyWith(
color:
(state is SelectedTabState) && state.selectedTab == true
? ColorsManager.whiteColors
: ColorsManager.grayColor,
fontWeight:
(state is SelectedTabState) && state.selectedTab == true
? FontWeight.w700
: FontWeight.w400,
color: state.routineTab ? ColorsManager.whiteColors : ColorsManager.grayColor,
fontWeight: state.routineTab ? FontWeight.w700 : FontWeight.w400,
),
),
),
@ -88,13 +69,12 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
);
}),
rightBody: const NavigateHomeGridView(),
scaffoldBody: BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
builder: (context, state) {
if (state is SelectedTabState && state.selectedTab) {
scaffoldBody: BlocBuilder<RoutineBloc, RoutineState>(builder: (context, state) {
if (state.routineTab) {
return const RoutinesView();
}
if (state is ShowCreateRoutineState && state.showCreateRoutine) {
return CreateNewRoutineView();
if (state.createRoutineView) {
return CreateNewRoutineView();
}
return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
@ -104,8 +84,7 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
} else if (deviceState is DeviceManagementLoaded) {
return DeviceManagementBody(devices: deviceState.devices);
} else if (deviceState is DeviceManagementFiltered) {
return DeviceManagementBody(
devices: deviceState.filteredDevices);
return DeviceManagementBody(devices: deviceState.filteredDevices);
} else {
return const Center(child: Text('Error fetching Devices'));
}

View File

@ -6,6 +6,7 @@ import 'package:syncrow_web/pages/auth/model/user_model.dart';
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
import 'package:syncrow_web/pages/home/home_model/home_item_model.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/services/home_api.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
@ -41,8 +42,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
Future _fetchUserInfo(FetchUserInfo event, Emitter<HomeState> emit) async {
try {
var uuid =
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
user = await HomeApi().fetchUserInfo(uuid);
emit(HomeInitial());
} catch (e) {
@ -84,6 +84,8 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
icon: Assets.devicesIcon,
active: true,
onPress: (context) {
BlocProvider.of<RoutineBloc>(context)
.add(const TriggerSwitchTabsEvent(isRoutineTab: false));
context.go(RoutesConst.deviceManagementPage);
},
color: ColorsManager.primaryColor,

View File

@ -13,7 +13,6 @@ import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
import 'package:syncrow_web/services/routines_api.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/navigation_service.dart';
import 'package:uuid/uuid.dart';
part 'routine_event.dart';
@ -46,14 +45,35 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
on<UpdateScene>(_onUpdateScene);
on<UpdateAutomation>(_onUpdateAutomation);
on<SetAutomationActionExecutor>(_onSetAutomationActionExecutor);
on<TriggerSwitchTabsEvent>(_triggerSwitchTabsEvent);
on<CreateNewRoutineViewEvent>(_createNewRoutineViewEvent);
}
FutureOr<void> _triggerSwitchTabsEvent(
TriggerSwitchTabsEvent event,
Emitter<RoutineState> emit,
) {
emit(state.copyWith(routineTab: event.isRoutineTab, createRoutineView: false));
add(ResetRoutineState());
if (event.isRoutineTab) {
add(const LoadScenes(spaceId, communityId));
add(const LoadAutomation(spaceId));
}
}
FutureOr<void> _createNewRoutineViewEvent(
CreateNewRoutineViewEvent event,
Emitter<RoutineState> emit,
) {
emit(state.copyWith(createRoutineView: event.createRoutineView));
}
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems);
// Find the index of the item in teh current itemsList
int index = updatedIfItems.indexWhere(
(map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
int index =
updatedIfItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
// Replace the map if the index is valid
if (index != -1) {
updatedIfItems[index] = event.item;
@ -62,21 +82,18 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
if (event.isTabToRun) {
emit(state.copyWith(
ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
} else {
emit(state.copyWith(
ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
}
}
void _onAddToThenContainer(
AddToThenContainer event, Emitter<RoutineState> emit) {
void _onAddToThenContainer(AddToThenContainer event, Emitter<RoutineState> emit) {
final currentItems = List<Map<String, dynamic>>.from(state.thenItems);
// Find the index of the item in teh current itemsList
int index = currentItems.indexWhere(
(map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
int index =
currentItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
// Replace the map if the index is valid
if (index != -1) {
currentItems[index] = event.item;
@ -87,26 +104,22 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
emit(state.copyWith(thenItems: currentItems));
}
void _onAddFunctionsToRoutine(
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
void _onAddFunctionsToRoutine(AddFunctionToRoutine event, Emitter<RoutineState> emit) {
try {
if (event.functions.isEmpty) return;
List<DeviceFunctionData> selectedFunction =
List<DeviceFunctionData>.from(event.functions);
List<DeviceFunctionData> selectedFunction = List<DeviceFunctionData>.from(event.functions);
Map<String, List<DeviceFunctionData>> currentSelectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
List<DeviceFunctionData> currentFunctions =
List<DeviceFunctionData>.from(
currentSelectedFunctions[event.uniqueCustomId] ?? []);
List<DeviceFunctionData>.from(currentSelectedFunctions[event.uniqueCustomId] ?? []);
List<String> functionCode = [];
for (int i = 0; i < selectedFunction.length; i++) {
for (int j = 0; j < currentFunctions.length; j++) {
if (selectedFunction[i].functionCode ==
currentFunctions[j].functionCode) {
if (selectedFunction[i].functionCode == currentFunctions[j].functionCode) {
currentFunctions[j] = selectedFunction[i];
if (!functionCode.contains(currentFunctions[j].functionCode)) {
functionCode.add(currentFunctions[j].functionCode);
@ -116,15 +129,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
for (int i = 0; i < functionCode.length; i++) {
selectedFunction
.removeWhere((code) => code.functionCode == functionCode[i]);
selectedFunction.removeWhere((code) => code.functionCode == functionCode[i]);
}
currentSelectedFunctions[event.uniqueCustomId] =
List.from(currentFunctions)..addAll(selectedFunction);
currentSelectedFunctions[event.uniqueCustomId] = List.from(currentFunctions)
..addAll(selectedFunction);
} else {
currentSelectedFunctions[event.uniqueCustomId] =
List.from(event.functions);
currentSelectedFunctions[event.uniqueCustomId] = List.from(event.functions);
}
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
@ -133,13 +144,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
Future<void> _onLoadScenes(
LoadScenes event, Emitter<RoutineState> emit) async {
Future<void> _onLoadScenes(LoadScenes event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null));
try {
final scenes =
await SceneApi.getScenesByUnitId(event.unitId, event.communityId);
final scenes = await SceneApi.getScenesByUnitId(event.unitId, event.communityId);
emit(state.copyWith(
scenes: scenes,
isLoading: false,
@ -154,8 +163,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
Future<void> _onLoadAutomation(
LoadAutomation event, Emitter<RoutineState> emit) async {
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null));
try {
@ -183,16 +191,14 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
FutureOr<void> _onSearchRoutines(
SearchRoutines event, Emitter<RoutineState> emit) async {
FutureOr<void> _onSearchRoutines(SearchRoutines event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null));
await Future.delayed(const Duration(seconds: 1));
emit(state.copyWith(isLoading: false, errorMessage: null));
emit(state.copyWith(searchText: event.query));
}
FutureOr<void> _onAddSelectedIcon(
AddSelectedIcon event, Emitter<RoutineState> emit) {
FutureOr<void> _onAddSelectedIcon(AddSelectedIcon event, Emitter<RoutineState> emit) {
emit(state.copyWith(selectedIcon: event.icon));
}
@ -206,8 +212,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
return actions.last['deviceId'] == 'delay';
}
Future<void> _onCreateScene(
CreateSceneEvent event, Emitter<RoutineState> emit) async {
Future<void> _onCreateScene(CreateSceneEvent event, Emitter<RoutineState> emit) async {
try {
// Check if first action is delay
if (_isFirstActionDelay(state.thenItems)) {
@ -267,21 +272,20 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
spaceUuid: spaceId,
iconId: state.selectedIcon ?? '',
showInDevice: true,
sceneName: state.routineName!,
sceneName: state.routineName ?? '',
decisionExpr: 'and',
actions: actions,
);
final result = await SceneApi.createScene(createSceneModel);
if (result['success']) {
Navigator.of(NavigationService.navigatorKey.currentContext!).pop();
add(ResetRoutineState());
add(const LoadScenes(spaceId, communityId));
add(const LoadAutomation(spaceId));
} else {
emit(state.copyWith(
isLoading: false,
errorMessage: result['message'],
errorMessage: 'Something went wrong',
));
}
} catch (e) {
@ -292,8 +296,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
Future<void> _onCreateAutomation(
CreateAutomationEvent event, Emitter<RoutineState> emit) async {
Future<void> _onCreateAutomation(CreateAutomationEvent event, Emitter<RoutineState> emit) async {
try {
if (state.routineName == null || state.routineName!.isEmpty) {
emit(state.copyWith(
@ -378,7 +381,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final createAutomationModel = CreateAutomationModel(
spaceUuid: spaceId,
automationName: state.routineName!,
automationName: state.routineName ?? '',
decisionExpr: state.selectedAutomationOperator,
effectiveTime: EffectiveTime(
start: state.effectiveTime?.start ?? '00:00',
@ -391,7 +394,6 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final result = await SceneApi.createAutomation(createAutomationModel);
if (result['success']) {
Navigator.of(NavigationService.navigatorKey.currentContext!).pop();
add(ResetRoutineState());
add(const LoadAutomation(spaceId));
add(const LoadScenes(spaceId, communityId));
@ -409,21 +411,17 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
FutureOr<void> _onRemoveDragCard(
RemoveDragCard event, Emitter<RoutineState> emit) {
FutureOr<void> _onRemoveDragCard(RemoveDragCard event, Emitter<RoutineState> emit) {
if (event.isFromThen) {
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
final selectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
thenItems.removeAt(event.index);
selectedFunctions.remove(event.key);
emit(state.copyWith(
thenItems: thenItems, selectedFunctions: selectedFunctions));
emit(state.copyWith(thenItems: thenItems, selectedFunctions: selectedFunctions));
} else {
final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
final selectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
ifItems.removeAt(event.index);
selectedFunctions.remove(event.key);
@ -434,8 +432,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
isAutomation: false,
isTabToRun: false));
} else {
emit(state.copyWith(
ifItems: ifItems, selectedFunctions: selectedFunctions));
emit(state.copyWith(ifItems: ifItems, selectedFunctions: selectedFunctions));
}
}
}
@ -447,21 +444,18 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
));
}
FutureOr<void> _onEffectiveTimeEvent(
EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
FutureOr<void> _onEffectiveTimeEvent(EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
emit(state.copyWith(effectiveTime: event.effectiveTime));
}
FutureOr<void> _onSetRoutineName(
SetRoutineName event, Emitter<RoutineState> emit) {
emit(state.copyWith(routineName: event.name));
FutureOr<void> _onSetRoutineName(SetRoutineName event, Emitter<RoutineState> emit) {
emit(state.copyWith(
routineName: event.name,
));
}
(
List<Map<String, dynamic>>,
List<Map<String, dynamic>>,
Map<String, List<DeviceFunctionData>>
) _createCardData(
(List<Map<String, dynamic>>, List<Map<String, dynamic>>, Map<String, List<DeviceFunctionData>>)
_createCardData(
List<RoutineAction> actions,
List<RoutineCondition>? conditions,
Map<String, List<DeviceFunctionData>> currentFunctions,
@ -494,8 +488,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
'deviceId': condition.entityId,
'title': matchingDevice.name ?? condition.entityId,
'productType': condition.entityType,
'imagePath':
matchingDevice.getDefaultIcon(condition.entityType),
'imagePath': matchingDevice.getDefaultIcon(condition.entityType),
};
final functions = matchingDevice.functions;
@ -531,11 +524,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final cardData = {
'entityId': action.entityId,
'uniqueCustomId': const Uuid().v4(),
'deviceId':
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'title': action.actionExecutor == 'delay'
? 'Delay'
: (matchingDevice.name ?? 'Device'),
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'title': action.actionExecutor == 'delay' ? 'Delay' : (matchingDevice.name ?? 'Device'),
'productType': action.productType,
'imagePath': matchingDevice.getDefaultIcon(action.productType),
};
@ -578,8 +568,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
return (thenItems, ifItems, currentFunctions);
}
Future<void> _onGetSceneDetails(
GetSceneDetails event, Emitter<RoutineState> emit) async {
Future<void> _onGetSceneDetails(GetSceneDetails event, Emitter<RoutineState> emit) async {
try {
emit(state.copyWith(
isLoading: true,
@ -591,7 +580,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
selectedFunctions: {},
ifItems: [],
thenItems: [],
errorMessage: null,
errorMessage: '',
loadScenesErrorMessage: null,
loadAutomationErrorMessage: null,
searchText: '',
@ -627,12 +616,10 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (!deviceCards.containsKey(deviceId)) {
deviceCards[deviceId] = {
'entityId': action.entityId,
'deviceId':
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'uniqueCustomId':
action.type == 'automation' || action.actionExecutor == 'delay'
? const Uuid().v4()
: action.entityId,
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'uniqueCustomId': action.type == 'automation' || action.actionExecutor == 'delay'
? const Uuid().v4()
: action.entityId,
'title': action.actionExecutor == 'delay'
? 'Delay'
: action.type == 'automation'
@ -667,8 +654,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
),
);
emit(state.copyWith(automationActionExecutor: action.actionExecutor));
} else if (action.executorProperty != null &&
action.actionExecutor != 'delay') {
} else if (action.executorProperty != null && action.actionExecutor != 'delay') {
if (!updatedFunctions.containsKey(uniqueCustomId)) {
updatedFunctions[uniqueCustomId] = [];
}
@ -753,8 +739,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
thenItems: [],
));
final automationDetails =
await SceneApi.getAutomationDetails(event.automationId);
final automationDetails = await SceneApi.getAutomationDetails(event.automationId);
final List<Map<String, dynamic>> thenItems;
final List<Map<String, dynamic>> ifItems;
@ -773,16 +758,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final cardData = {
'entityId': condition.entityId,
'uniqueCustomId': const Uuid().v4(),
'deviceId': condition.expr.statusCode == 'delay'
? 'delay'
: condition.entityId,
'deviceId': condition.expr.statusCode == 'delay' ? 'delay' : condition.entityId,
'title': condition.expr.statusCode == 'delay'
? 'Delay'
: (matchingDevice?.name ?? 'Device'),
'productType': condition.productType,
'functions': matchingDevice?.functions ?? [],
'imagePath':
matchingDevice?.getDefaultIcon(condition.productType) ?? '',
'imagePath': matchingDevice?.getDefaultIcon(condition.productType) ?? '',
'device': matchingDevice,
};
@ -819,19 +801,15 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final cardData = {
'entityId': action.entityId,
'uniqueCustomId': const Uuid().v4(),
'deviceId':
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'title': action.actionExecutor == 'delay'
? 'Delay'
: (matchingDevice.name ?? 'Device'),
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'title': action.actionExecutor == 'delay' ? 'Delay' : (matchingDevice.name ?? 'Device'),
'productType': action.productType,
'functions': matchingDevice.functions,
'imagePath': matchingDevice.getDefaultIcon(action.productType),
'device': matchingDevice,
};
if (action.executorProperty != null &&
action.actionExecutor != 'delay') {
if (action.executorProperty != null && action.actionExecutor != 'delay') {
final functions = matchingDevice.functions;
final functionCode = action.executorProperty!.functionCode;
for (var function in functions) {
@ -894,26 +872,26 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
FutureOr<void> _onResetRoutineState(
ResetRoutineState event, Emitter<RoutineState> emit) {
FutureOr<void> _onResetRoutineState(ResetRoutineState event, Emitter<RoutineState> emit) {
emit(state.copyWith(
ifItems: [],
thenItems: [],
selectedFunctions: {},
scenes: [],
automations: [],
isLoading: false,
errorMessage: null,
loadScenesErrorMessage: null,
loadAutomationErrorMessage: null,
searchText: '',
selectedIcon: null,
isTabToRun: false,
isAutomation: false,
selectedAutomationOperator: 'or',
effectiveTime: null,
routineName: null,
));
ifItems: [],
thenItems: [],
selectedFunctions: {},
scenes: [],
automations: [],
isLoading: false,
errorMessage: '',
loadScenesErrorMessage: null,
loadAutomationErrorMessage: null,
searchText: '',
selectedIcon: null,
isTabToRun: false,
isAutomation: false,
selectedAutomationOperator: 'or',
effectiveTime: null,
routineName: '',
isUpdate: false,
createRoutineView: false));
}
FutureOr<void> _deleteScene(DeleteScene event, Emitter<RoutineState> emit) {
@ -922,13 +900,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (state.isTabToRun) {
SceneApi.deleteScene(unitUuid: spaceId, sceneId: state.sceneId ?? '');
} else {
SceneApi.deleteAutomation(
unitUuid: spaceId, automationId: state.automationId ?? '');
SceneApi.deleteAutomation(unitUuid: spaceId, automationId: state.automationId ?? '');
}
add(const LoadScenes(spaceId, communityId));
add(const LoadAutomation(spaceId));
add(ResetRoutineState());
emit(state.copyWith(isLoading: false, createRoutineView: false));
} catch (e) {
emit(state.copyWith(
isLoading: false,
@ -951,8 +929,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
// }
// }
FutureOr<void> _fetchDevices(
FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
FutureOr<void> _fetchDevices(FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true));
try {
final devices = await DevicesManagementApi().fetchDevices();
@ -963,8 +940,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
FutureOr<void> _onUpdateScene(
UpdateScene event, Emitter<RoutineState> emit) async {
FutureOr<void> _onUpdateScene(UpdateScene event, Emitter<RoutineState> emit) async {
try {
// Check if first action is delay
if (_isFirstActionDelay(state.thenItems)) {
@ -1030,10 +1006,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
actions: actions,
);
final result =
await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
final result = await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
if (result['success']) {
Navigator.of(NavigationService.navigatorKey.currentContext!).pop();
add(ResetRoutineState());
add(const LoadScenes(spaceId, communityId));
add(const LoadAutomation(spaceId));
@ -1051,8 +1025,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}
}
FutureOr<void> _onUpdateAutomation(
UpdateAutomation event, Emitter<RoutineState> emit) async {
FutureOr<void> _onUpdateAutomation(UpdateAutomation event, Emitter<RoutineState> emit) async {
if (_isFirstActionDelay(state.thenItems)) {
emit(state.copyWith(
errorMessage: 'Cannot have delay as the first action',
@ -1064,8 +1037,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
try {
final conditions = state.ifItems
.map((item) {
final functions =
state.selectedFunctions[item['uniqueCustomId']] ?? [];
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
if (functions.isEmpty) return null;
final function = functions.first;
@ -1085,8 +1057,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final actions = state.thenItems
.map((item) {
final functions =
state.selectedFunctions[item['uniqueCustomId']] ?? [];
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
if (functions.isEmpty) return null;
final function = functions.first;
@ -1096,9 +1067,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
executorProperty: ExecutorProperty(
functionCode: function.functionCode,
functionValue: function.value,
delaySeconds: function.functionCode == 'delay'
? (function.value as num).toInt()
: null,
delaySeconds:
function.functionCode == 'delay' ? (function.value as num).toInt() : null,
),
);
})
@ -1109,17 +1079,24 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
spaceUuid: spaceId,
automationName: state.routineName ?? '',
decisionExpr: state.selectedAutomationOperator,
effectiveTime:
state.effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
effectiveTime: state.effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
conditions: conditions,
actions: actions,
);
await SceneApi.updateAutomation(
createAutomationModel, state.automationId ?? '');
final result =
await SceneApi.updateAutomation(createAutomationModel, state.automationId ?? '');
add(const LoadAutomation(spaceId));
emit(state.copyWith(isLoading: false));
if (result['success']) {
add(ResetRoutineState());
add(const LoadScenes(spaceId, communityId));
add(const LoadAutomation(spaceId));
} else {
emit(state.copyWith(
isLoading: false,
errorMessage: result['message'],
));
}
} catch (e) {
emit(state.copyWith(
isLoading: false,
@ -1130,7 +1107,6 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
FutureOr<void> _onSetAutomationActionExecutor(
SetAutomationActionExecutor event, Emitter<RoutineState> emit) {
emit(state.copyWith(
automationActionExecutor: event.automationActionExecutor));
emit(state.copyWith(automationActionExecutor: event.automationActionExecutor));
}
}

View File

@ -187,6 +187,20 @@ class SetAutomationActionExecutor extends RoutineEvent {
List<Object> get props => [automationActionExecutor];
}
class TriggerSwitchTabsEvent extends RoutineEvent {
final bool isRoutineTab;
const TriggerSwitchTabsEvent({required this.isRoutineTab});
@override
List<Object> get props => [isRoutineTab];
}
class CreateNewRoutineViewEvent extends RoutineEvent {
final bool createRoutineView;
const CreateNewRoutineViewEvent({required this.createRoutineView});
@override
List<Object> get props => [createRoutineView];
}
class FetchDevicesInRoutine extends RoutineEvent {}
class ResetRoutineState extends RoutineEvent {}

View File

@ -23,31 +23,34 @@ class RoutineState extends Equatable {
final bool? isUpdate;
final List<AllDevicesModel> devices;
final String? automationActionExecutor;
final bool routineTab;
final bool createRoutineView;
const RoutineState({
this.ifItems = const [],
this.thenItems = const [],
this.availableCards = const [],
this.scenes = const [],
this.automations = const [],
this.selectedFunctions = const {},
this.isLoading = false,
this.errorMessage,
this.routineName,
this.selectedIcon,
this.loadScenesErrorMessage,
this.loadAutomationErrorMessage,
this.searchText,
this.isTabToRun = false,
this.isAutomation = false,
this.selectedAutomationOperator = 'or',
this.effectiveTime,
this.sceneId,
this.automationId,
this.isUpdate,
this.devices = const [],
this.automationActionExecutor,
});
const RoutineState(
{this.ifItems = const [],
this.thenItems = const [],
this.availableCards = const [],
this.scenes = const [],
this.automations = const [],
this.selectedFunctions = const {},
this.isLoading = false,
this.errorMessage,
this.routineName,
this.selectedIcon,
this.loadScenesErrorMessage,
this.loadAutomationErrorMessage,
this.searchText,
this.isTabToRun = false,
this.isAutomation = false,
this.selectedAutomationOperator = 'or',
this.effectiveTime,
this.sceneId,
this.automationId,
this.isUpdate,
this.devices = const [],
this.automationActionExecutor,
this.routineTab = false,
this.createRoutineView = false});
RoutineState copyWith({
List<Map<String, dynamic>>? ifItems,
@ -71,34 +74,34 @@ class RoutineState extends Equatable {
bool? isUpdate,
List<AllDevicesModel>? devices,
String? automationActionExecutor,
TextEditingController? nameController,
bool? routineTab,
bool? createRoutineView,
}) {
return RoutineState(
ifItems: ifItems ?? this.ifItems,
thenItems: thenItems ?? this.thenItems,
scenes: scenes ?? this.scenes,
automations: automations ?? this.automations,
selectedFunctions: selectedFunctions ?? this.selectedFunctions,
isLoading: isLoading ?? this.isLoading,
errorMessage: errorMessage ?? this.errorMessage,
routineName: routineName ?? this.routineName,
selectedIcon: selectedIcon ?? this.selectedIcon,
loadScenesErrorMessage:
loadScenesErrorMessage ?? this.loadScenesErrorMessage,
loadAutomationErrorMessage:
loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
searchText: searchText ?? this.searchText,
isTabToRun: isTabToRun ?? this.isTabToRun,
isAutomation: isAutomation ?? this.isAutomation,
selectedAutomationOperator:
selectedAutomationOperator ?? this.selectedAutomationOperator,
effectiveTime: effectiveTime ?? this.effectiveTime,
sceneId: sceneId ?? this.sceneId,
automationId: automationId ?? this.automationId,
isUpdate: isUpdate ?? this.isUpdate,
devices: devices ?? this.devices,
automationActionExecutor:
automationActionExecutor ?? this.automationActionExecutor,
);
ifItems: ifItems ?? this.ifItems,
thenItems: thenItems ?? this.thenItems,
scenes: scenes ?? this.scenes,
automations: automations ?? this.automations,
selectedFunctions: selectedFunctions ?? this.selectedFunctions,
isLoading: isLoading ?? this.isLoading,
errorMessage: errorMessage ?? this.errorMessage,
routineName: routineName ?? this.routineName,
selectedIcon: selectedIcon ?? this.selectedIcon,
loadScenesErrorMessage: loadScenesErrorMessage ?? this.loadScenesErrorMessage,
loadAutomationErrorMessage: loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
searchText: searchText ?? this.searchText,
isTabToRun: isTabToRun ?? this.isTabToRun,
isAutomation: isAutomation ?? this.isAutomation,
selectedAutomationOperator: selectedAutomationOperator ?? this.selectedAutomationOperator,
effectiveTime: effectiveTime ?? this.effectiveTime,
sceneId: sceneId ?? this.sceneId,
automationId: automationId ?? this.automationId,
isUpdate: isUpdate ?? this.isUpdate,
devices: devices ?? this.devices,
automationActionExecutor: automationActionExecutor ?? this.automationActionExecutor,
routineTab: routineTab ?? this.routineTab,
createRoutineView: createRoutineView ?? this.createRoutineView);
}
@override
@ -124,5 +127,7 @@ class RoutineState extends Equatable {
isUpdate,
devices,
automationActionExecutor,
routineTab,
createRoutineView
];
}

View File

@ -8,8 +8,8 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class SaveRoutineHelper {
static Future<bool?> showSaveRoutineDialog(BuildContext context) async {
return showDialog<bool?>(
static Future<void> showSaveRoutineDialog(BuildContext context) async {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return BlocBuilder<RoutineBloc, RoutineState>(
@ -54,27 +54,23 @@ class SaveRoutineHelper {
),
if (state.isAutomation)
...state.ifItems.map((item) {
final functions = state.selectedFunctions[
item['uniqueCustomId']] ??
[];
final functions =
state.selectedFunctions[item['uniqueCustomId']] ?? [];
return ListTile(
leading: SvgPicture.asset(
item['imagePath'],
width: 22,
height: 22,
),
title: Text(item['title'],
style: const TextStyle(fontSize: 14)),
title:
Text(item['title'], style: const TextStyle(fontSize: 14)),
subtitle: Wrap(
children: functions
.map((f) => Text(
'${f.operationName}: ${f.value}, ',
style: const TextStyle(
color: ColorsManager
.grayColor,
fontSize: 8),
overflow:
TextOverflow.ellipsis,
color: ColorsManager.grayColor, fontSize: 8),
overflow: TextOverflow.ellipsis,
maxLines: 3,
))
.toList(),
@ -99,25 +95,22 @@ class SaveRoutineHelper {
),
const SizedBox(height: 8),
...state.thenItems.map((item) {
final functions = state.selectedFunctions[
item['uniqueCustomId']] ??
[];
final functions =
state.selectedFunctions[item['uniqueCustomId']] ?? [];
return ListTile(
leading: SvgPicture.asset(
item['imagePath'],
width: 22,
height: 22,
),
title: Text(item['title'],
style: const TextStyle(fontSize: 14)),
title:
Text(item['title'], style: const TextStyle(fontSize: 14)),
subtitle: Wrap(
children: functions
.map((f) => Text(
'${f.operationName}: ${f.value}, ',
style: const TextStyle(
color:
ColorsManager.grayColor,
fontSize: 8),
color: ColorsManager.grayColor, fontSize: 8),
overflow: TextOverflow.ellipsis,
maxLines: 3,
))
@ -131,7 +124,7 @@ class SaveRoutineHelper {
],
),
),
if (state.errorMessage != null)
if (state.errorMessage != null || state.errorMessage!.isNotEmpty)
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
@ -140,32 +133,24 @@ class SaveRoutineHelper {
),
),
DialogFooter(
onCancel: () => Navigator.pop(context, false),
onCancel: () => Navigator.pop(context),
onConfirm: () {
if (state.isAutomation) {
if (state.automationId != null) {
context
.read<RoutineBloc>()
.add(const UpdateAutomation());
context.read<RoutineBloc>().add(const UpdateAutomation());
} else {
context
.read<RoutineBloc>()
.add(const CreateAutomationEvent());
context.read<RoutineBloc>().add(const CreateAutomationEvent());
}
} else {
if (state.sceneId != null) {
context
.read<RoutineBloc>()
.add(const UpdateScene());
context.read<RoutineBloc>().add(const UpdateScene());
} else {
context
.read<RoutineBloc>()
.add(const CreateSceneEvent());
context.read<RoutineBloc>().add(const CreateSceneEvent());
}
}
if (context.read<RoutineBloc>().state.errorMessage ==
null) {
Navigator.pop(context, true);
if (context.read<RoutineBloc>().state.errorMessage == null ||
context.read<RoutineBloc>().state.errorMessage!.isEmpty) {
Navigator.pop(context);
}
},
isConfirmEnabled: true,

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.dart';
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/fetch_routine_scenes_automation.dart';
@ -23,12 +22,10 @@ class _RoutinesViewState extends State<RoutinesView> {
@override
Widget build(BuildContext context) {
return BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
return BlocBuilder<RoutineBloc, RoutineState>(
builder: (context, state) {
if (state is ShowCreateRoutineState && state.showCreateRoutine) {
return const CreateNewRoutineView(
);
if (state.createRoutineView) {
return const CreateNewRoutineView();
}
return Padding(
padding: const EdgeInsets.all(16),
@ -49,12 +46,12 @@ class _RoutinesViewState extends State<RoutinesView> {
),
RoutineViewCard(
onTap: () {
BlocProvider.of<SwitchTabsBloc>(context).add(
const CreateNewRoutineViewEvent(true),
);
context.read<RoutineBloc>().add(
(ResetRoutineState()),
);
BlocProvider.of<RoutineBloc>(context).add(
const CreateNewRoutineViewEvent(createRoutineView: true),
);
},
icon: Icons.add,
textString: '',

View File

@ -33,31 +33,24 @@ class DeleteSceneWidget extends StatelessWidget {
alignment: AlignmentDirectional.center,
child: Text(
'Cancel',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: ColorsManager.textGray,
),
),
),
),
Container(
width: 1, height: 50, color: ColorsManager.greyColor),
Container(width: 1, height: 50, color: ColorsManager.greyColor),
InkWell(
onTap: () {
context.read<RoutineBloc>().add(const DeleteScene());
Navigator.of(context).pop();
Navigator.of(context).pop(true);
Navigator.of(context).pop();
},
child: Container(
alignment: AlignmentDirectional.center,
child: Text(
'Confirm',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: ColorsManager.primaryColorWithOpacity,
),
),

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/routine_view_card.dart';
import 'package:syncrow_web/utils/color_manager.dart';
@ -69,8 +68,8 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
),
child: RoutineViewCard(
onTap: () {
BlocProvider.of<SwitchTabsBloc>(context).add(
const CreateNewRoutineViewEvent(true),
BlocProvider.of<RoutineBloc>(context).add(
const CreateNewRoutineViewEvent(createRoutineView: true),
);
context.read<RoutineBloc>().add(
GetSceneDetails(
@ -118,8 +117,8 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
),
child: RoutineViewCard(
onTap: () {
BlocProvider.of<SwitchTabsBloc>(context).add(
const CreateNewRoutineViewEvent(true),
BlocProvider.of<RoutineBloc>(context).add(
const CreateNewRoutineViewEvent(createRoutineView: true),
);
context.read<RoutineBloc>().add(
GetAutomationDetails(

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
@ -49,11 +48,11 @@ class DiscardDialog {
onConfirm: () {
context.read<RoutineBloc>().add(ResetRoutineState());
Navigator.pop(context);
BlocProvider.of<SwitchTabsBloc>(context).add(
const CreateNewRoutineViewEvent(false),
BlocProvider.of<RoutineBloc>(context).add(
const CreateNewRoutineViewEvent(createRoutineView: false),
);
BlocProvider.of<SwitchTabsBloc>(context).add(
const TriggerSwitchTabsEvent(true),
BlocProvider.of<RoutineBloc>(context).add(
const TriggerSwitchTabsEvent(isRoutineTab: true),
);
});
}

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routiens/helper/save_routine_helper.dart';
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/discard_dialog.dart';
@ -16,8 +15,7 @@ class RoutineSearchAndButtons extends StatefulWidget {
});
@override
State<RoutineSearchAndButtons> createState() =>
_RoutineSearchAndButtonsState();
State<RoutineSearchAndButtons> createState() => _RoutineSearchAndButtonsState();
}
class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
@ -37,15 +35,9 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
@override
Widget build(BuildContext context) {
return BlocConsumer<RoutineBloc, RoutineState>(
listenWhen: (previous, current) =>
previous.routineName != current.routineName,
listener: (context, state) {
if (state.routineName != _nameController.text) {
_nameController.text = state.routineName ?? '';
}
},
return BlocBuilder<RoutineBloc, RoutineState>(
builder: (context, state) {
_nameController.text = state.routineName ?? '';
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Wrap(
@ -62,9 +54,8 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
children: [
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: constraints.maxWidth > 700
? 450
: constraints.maxWidth - 32),
maxWidth:
constraints.maxWidth > 700 ? 450 : constraints.maxWidth - 32),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
@ -73,13 +64,10 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
children: [
Text('* ',
style: context.textTheme.bodyMedium!
.copyWith(
color: ColorsManager.red,
fontSize: 13)),
.copyWith(color: ColorsManager.red, fontSize: 13)),
Text(
'Routine Name',
style: context.textTheme.bodyMedium!
.copyWith(
style: context.textTheme.bodyMedium!.copyWith(
fontSize: 13,
fontWeight: FontWeight.w600,
color: ColorsManager.blackColor,
@ -93,24 +81,20 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
decoration: containerWhiteDecoration,
child: TextFormField(
style: context.textTheme.bodyMedium!
.copyWith(
color: ColorsManager.blackColor),
.copyWith(color: ColorsManager.blackColor),
controller: _nameController,
decoration: InputDecoration(
hintText: 'Please enter the name',
hintStyle: context.textTheme.bodyMedium!
.copyWith(
fontSize: 12,
color: ColorsManager.grayColor),
.copyWith(fontSize: 12, color: ColorsManager.grayColor),
contentPadding:
const EdgeInsets.symmetric(
horizontal: 12, vertical: 10),
const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
border: InputBorder.none,
),
onChanged: (value) {
onTapOutside: (_) {
context
.read<RoutineBloc>()
.add(SetRoutineName(value));
.add(SetRoutineName(_nameController.text));
},
validator: (value) {
if (value == null || value.isEmpty) {
@ -130,18 +114,16 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
width: 200,
child: Center(
child: DefaultButton(
onPressed: state.isAutomation ||
state.isTabToRun
onPressed: state.isAutomation || state.isTabToRun
? () async {
final result = await SettingHelper
.showSettingDialog(
final result = await SettingHelper.showSettingDialog(
context: context,
iconId:
state.selectedIcon ?? '',
iconId: state.selectedIcon ?? '',
);
if (result != null) {
context.read<RoutineBloc>().add(
AddSelectedIcon(result));
context
.read<RoutineBloc>()
.add(AddSelectedIcon(result));
}
}
: null,
@ -197,12 +179,10 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
child: Center(
child: DefaultButton(
onPressed: () async {
if (state.routineName == null ||
state.routineName!.isEmpty) {
if (state.routineName == null || state.routineName!.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text(
'Please enter the routine name'),
content: const Text('Please enter the routine name'),
duration: const Duration(seconds: 2),
backgroundColor: ColorsManager.red,
action: SnackBarAction(
@ -216,12 +196,10 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
return;
}
if (state.ifItems.isEmpty ||
state.thenItems.isEmpty) {
if (state.ifItems.isEmpty || state.thenItems.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text(
'Please add if and then condition'),
content: const Text('Please add if and then condition'),
duration: const Duration(seconds: 2),
backgroundColor: ColorsManager.red,
action: SnackBarAction(
@ -234,18 +212,17 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
);
return;
}
final result = await SaveRoutineHelper
.showSaveRoutineDialog(context);
if (result != null && result) {
BlocProvider.of<SwitchTabsBloc>(context)
.add(
const CreateNewRoutineViewEvent(false),
);
BlocProvider.of<SwitchTabsBloc>(context)
.add(
const TriggerSwitchTabsEvent(true),
);
}
// final result =
// await
SaveRoutineHelper.showSaveRoutineDialog(context);
// if (result != null && result) {
// BlocProvider.of<RoutineBloc>(context).add(
// const CreateNewRoutineViewEvent(createRoutineView: false),
// );
// BlocProvider.of<RoutineBloc>(context).add(
// const TriggerSwitchTabsEvent(isRoutineTab: true),
// );
// }
},
borderRadius: 15,
elevation: 0,
@ -276,14 +253,10 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
child: DefaultButton(
onPressed: state.isAutomation || state.isTabToRun
? () async {
final result =
await SettingHelper.showSettingDialog(
context: context,
iconId: state.selectedIcon ?? '');
final result = await SettingHelper.showSettingDialog(
context: context, iconId: state.selectedIcon ?? '');
if (result != null) {
context
.read<RoutineBloc>()
.add(AddSelectedIcon(result));
context.read<RoutineBloc>().add(AddSelectedIcon(result));
}
}
: null,
@ -333,12 +306,10 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
child: Center(
child: DefaultButton(
onPressed: () async {
if (state.routineName == null ||
state.routineName!.isEmpty) {
if (state.routineName == null || state.routineName!.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text(
'Please enter the routine name'),
content: const Text('Please enter the routine name'),
duration: const Duration(seconds: 2),
backgroundColor: ColorsManager.red,
action: SnackBarAction(
@ -352,12 +323,10 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
return;
}
if (state.ifItems.isEmpty ||
state.thenItems.isEmpty) {
if (state.ifItems.isEmpty || state.thenItems.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text(
'Please add if and then condition'),
content: const Text('Please add if and then condition'),
duration: const Duration(seconds: 2),
backgroundColor: ColorsManager.red,
action: SnackBarAction(
@ -370,17 +339,17 @@ class _RoutineSearchAndButtonsState extends State<RoutineSearchAndButtons> {
);
return;
}
final result =
await SaveRoutineHelper.showSaveRoutineDialog(
context);
if (result != null && result) {
BlocProvider.of<SwitchTabsBloc>(context).add(
const CreateNewRoutineViewEvent(false),
);
BlocProvider.of<SwitchTabsBloc>(context).add(
const TriggerSwitchTabsEvent(true),
);
}
// final result =
// await
SaveRoutineHelper.showSaveRoutineDialog(context);
// if (result != null && result) {
// BlocProvider.of<RoutineBloc>(context).add(
// const CreateNewRoutineViewEvent(createRoutineView: false),
// );
// BlocProvider.of<RoutineBloc>(context).add(
// const TriggerSwitchTabsEvent(isRoutineTab: true),
// );
// }
},
borderRadius: 15,
elevation: 0,