mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-16 10:06:16 +00:00
finished select period dialog design
This commit is contained in:
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_state.dart';
|
||||||
|
|
||||||
|
class EffectPeriodBloc extends Bloc<EffectPeriodEvent, EffectPeriodState> {
|
||||||
|
EffectPeriodBloc() : super(EffectPeriodState.initial()) {
|
||||||
|
on<SetPeriod>(_onSetPeriod);
|
||||||
|
on<ToggleDay>(_onToggleDay);
|
||||||
|
on<SetCustomTime>(_onSetCustomTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSetPeriod(SetPeriod event, Emitter<EffectPeriodState> emit) {
|
||||||
|
emit(state.copyWith(selectedPeriod: event.period));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onToggleDay(ToggleDay event, Emitter<EffectPeriodState> emit) {
|
||||||
|
final days = List.of(state.selectedDays);
|
||||||
|
if (days.contains(event.day)) {
|
||||||
|
days.remove(event.day);
|
||||||
|
} else {
|
||||||
|
days.add(event.day);
|
||||||
|
}
|
||||||
|
emit(state.copyWith(selectedDays: days));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSetCustomTime(SetCustomTime event, Emitter<EffectPeriodState> emit) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
customStartTime: event.startTime, customEndTime: event.endTime));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
abstract class EffectPeriodEvent extends Equatable {
|
||||||
|
const EffectPeriodEvent();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetPeriod extends EffectPeriodEvent {
|
||||||
|
final String period;
|
||||||
|
|
||||||
|
const SetPeriod(this.period);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [period];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ToggleDay extends EffectPeriodEvent {
|
||||||
|
final String day;
|
||||||
|
|
||||||
|
const ToggleDay(this.day);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [day];
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetCustomTime extends EffectPeriodEvent {
|
||||||
|
final String startTime;
|
||||||
|
final String endTime;
|
||||||
|
|
||||||
|
const SetCustomTime(this.startTime, this.endTime);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [startTime, endTime];
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
class EffectPeriodState extends Equatable {
|
||||||
|
final String selectedPeriod;
|
||||||
|
final List<String> selectedDays;
|
||||||
|
final String? customStartTime;
|
||||||
|
final String? customEndTime;
|
||||||
|
|
||||||
|
const EffectPeriodState({
|
||||||
|
required this.selectedPeriod,
|
||||||
|
required this.selectedDays,
|
||||||
|
this.customStartTime,
|
||||||
|
this.customEndTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory EffectPeriodState.initial() {
|
||||||
|
return const EffectPeriodState(
|
||||||
|
selectedPeriod: 'All Day',
|
||||||
|
selectedDays: [],
|
||||||
|
customStartTime: null,
|
||||||
|
customEndTime: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectPeriodState copyWith({
|
||||||
|
String? selectedPeriod,
|
||||||
|
List<String>? selectedDays,
|
||||||
|
String? customStartTime,
|
||||||
|
String? customEndTime,
|
||||||
|
}) {
|
||||||
|
return EffectPeriodState(
|
||||||
|
selectedPeriod: selectedPeriod ?? this.selectedPeriod,
|
||||||
|
selectedDays: selectedDays ?? this.selectedDays,
|
||||||
|
customStartTime: customStartTime ?? this.customStartTime,
|
||||||
|
customEndTime: customEndTime ?? this.customEndTime,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props =>
|
||||||
|
[selectedPeriod, selectedDays, customStartTime, customEndTime];
|
||||||
|
}
|
62
lib/features/scene/view/scene_auto_settings.dart
Normal file
62
lib/features/scene/view/scene_auto_settings.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/widgets/bottom_sheet/effective_period_bottom_sheet.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
|
class SceneAutoSettings extends StatelessWidget {
|
||||||
|
const SceneAutoSettings({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final sceneSettings =
|
||||||
|
ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>? ??
|
||||||
|
{};
|
||||||
|
final sceneId = sceneSettings['sceneId'] as String? ?? '';
|
||||||
|
final isAutomation = sceneSettings['isAutomation'] as bool? ?? false;
|
||||||
|
final sceneName = sceneSettings['sceneName'] as String? ?? '';
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: ColorsManager.backgroundColor,
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: ColorsManager.backgroundColor,
|
||||||
|
title: const BodyLarge(
|
||||||
|
text: "Settings",
|
||||||
|
fontColor: ColorsManager.secondaryColor,
|
||||||
|
fontWeight: FontsManager.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: DefaultContainer(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SceneListTile(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
titleString: "Effective Period",
|
||||||
|
trailingWidget: const Icon(Icons.arrow_forward_ios_rounded),
|
||||||
|
onPressed: () {
|
||||||
|
context.customBottomSheet(
|
||||||
|
child: const EffectPeriodBottomSheetContent(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: sceneName.isNotEmpty,
|
||||||
|
child: DeleteBottomSheetContent(
|
||||||
|
isAutomation: isAutomation,
|
||||||
|
sceneId: sceneId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -40,15 +40,17 @@ class SceneTasksView extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 40,
|
width: 40,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: sceneSettings.sceneName.isEmpty
|
onTap: () {
|
||||||
? null
|
Navigator.pushNamed(
|
||||||
: () {
|
context,
|
||||||
context.customBottomSheet(
|
Routes.sceneAutoSettingsRoute,
|
||||||
child: DeleteBottomSheetContent(
|
arguments: {
|
||||||
sceneId: sceneSettings.sceneId,
|
"sceneId": sceneSettings.sceneId,
|
||||||
isAutomation: isAutomation),
|
"isAutomation": isAutomation,
|
||||||
);
|
"sceneName": sceneSettings.sceneName,
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.assetsIconsSettings,
|
Assets.assetsIconsSettings,
|
||||||
colorFilter: const ColorFilter.mode(
|
colorFilter: const ColorFilter.mode(
|
||||||
@ -109,48 +111,43 @@ class DeleteBottomSheetContent extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultContainer(
|
return DefaultContainer(
|
||||||
height: context.height * 0.2,
|
padding: EdgeInsets.zero,
|
||||||
child: ListView(
|
child: BlocConsumer<CreateSceneBloc, CreateSceneState>(
|
||||||
shrinkWrap: true,
|
listener: (context, state) {
|
||||||
children: [
|
if (state is DeleteSceneSuccess) {
|
||||||
BlocConsumer<CreateSceneBloc, CreateSceneState>(
|
if (state.success) {
|
||||||
listener: (context, state) {
|
navigateToRoute(context, Routes.homeRoute);
|
||||||
if (state is DeleteSceneSuccess) {
|
BlocProvider.of<SceneBloc>(context).add(
|
||||||
if (state.success) {
|
LoadScenes(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
navigateToRoute(context, Routes.homeRoute);
|
BlocProvider.of<SceneBloc>(context).add(
|
||||||
BlocProvider.of<SceneBloc>(context).add(
|
LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
LoadScenes(HomeCubit.getInstance().selectedSpace!.id!));
|
}
|
||||||
BlocProvider.of<SceneBloc>(context).add(LoadAutomation(
|
}
|
||||||
HomeCubit.getInstance().selectedSpace!.id!));
|
},
|
||||||
}
|
builder: (context, state) {
|
||||||
}
|
return DefaultContainer(
|
||||||
},
|
onTap: () {
|
||||||
builder: (context, state) {
|
context.read<CreateSceneBloc>().add(DeleteSceneEvent(
|
||||||
return DefaultContainer(
|
sceneId: sceneId,
|
||||||
onTap: () {
|
unitUuid: HomeCubit.getInstance().selectedSpace!.id!,
|
||||||
context.read<CreateSceneBloc>().add(DeleteSceneEvent(
|
));
|
||||||
sceneId: sceneId,
|
},
|
||||||
unitUuid:
|
child: SceneListTile(
|
||||||
HomeCubit.getInstance().selectedSpace!.id!,
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
));
|
titleString: isAutomation
|
||||||
},
|
? StringsManager.deleteAutomation
|
||||||
child: SceneListTile(
|
: StringsManager.deleteScene,
|
||||||
titleString: isAutomation
|
leadingWidget: (state is DeleteSceneLoading)
|
||||||
? StringsManager.deleteAutomation
|
? const SizedBox(
|
||||||
: StringsManager.deleteScene,
|
height: 24,
|
||||||
leadingWidget: (state is DeleteSceneLoading)
|
width: 24,
|
||||||
? const SizedBox(
|
child: CircularProgressIndicator())
|
||||||
height: 24,
|
: SvgPicture.asset(
|
||||||
width: 24,
|
Assets.assetsDeleteIcon,
|
||||||
child: CircularProgressIndicator())
|
color: ColorsManager.red,
|
||||||
: SvgPicture.asset(
|
),
|
||||||
Assets.assetsDeleteIcon,
|
));
|
||||||
color: ColorsManager.red,
|
},
|
||||||
),
|
|
||||||
));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,314 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_state.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
import 'package:time_picker_spinner/time_picker_spinner.dart';
|
||||||
|
|
||||||
|
class EffectPeriodBottomSheetContent extends StatefulWidget {
|
||||||
|
const EffectPeriodBottomSheetContent({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<EffectPeriodBottomSheetContent> createState() =>
|
||||||
|
_EffectPeriodBottomSheetContentState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EffectPeriodBottomSheetContentState
|
||||||
|
extends State<EffectPeriodBottomSheetContent> {
|
||||||
|
Future<List<String>?> showCustomTimePicker(BuildContext context) async {
|
||||||
|
String selectedStartTime = "00:00";
|
||||||
|
String selectedEndTime = "23:59";
|
||||||
|
PageController pageController = PageController(initialPage: 0);
|
||||||
|
|
||||||
|
DateTime startDateTime = DateTime(2022, 1, 1, 0, 0); // Fixed 00:00
|
||||||
|
DateTime endDateTime = DateTime(2022, 1, 1, 23, 59); // Fixed 23:59
|
||||||
|
|
||||||
|
context.customAlertDialog(
|
||||||
|
alertBody: SizedBox(
|
||||||
|
height: 250,
|
||||||
|
child: PageView(
|
||||||
|
controller: pageController,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {},
|
||||||
|
child: BodyMedium(
|
||||||
|
text: "Start",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
pageController.nextPage(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const BodyMedium(
|
||||||
|
text: "End",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TimePickerSpinner(
|
||||||
|
is24HourMode: false,
|
||||||
|
normalTextStyle: const TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
highlightedTextStyle: const TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
color: ColorsManager.primaryColor,
|
||||||
|
),
|
||||||
|
spacing: 20,
|
||||||
|
itemHeight: 50,
|
||||||
|
isForce2Digits: true,
|
||||||
|
time: startDateTime,
|
||||||
|
onTimeChange: (time) {
|
||||||
|
selectedStartTime =
|
||||||
|
"${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}";
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
pageController.previousPage(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const BodyMedium(text: "Start"),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {},
|
||||||
|
child: BodyMedium(
|
||||||
|
text: "End",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TimePickerSpinner(
|
||||||
|
is24HourMode: false,
|
||||||
|
normalTextStyle: const TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
highlightedTextStyle: const TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
color: ColorsManager.primaryColor,
|
||||||
|
),
|
||||||
|
spacing: 20,
|
||||||
|
itemHeight: 50,
|
||||||
|
isForce2Digits: true,
|
||||||
|
time: endDateTime,
|
||||||
|
onTimeChange: (time) {
|
||||||
|
selectedEndTime =
|
||||||
|
"${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}";
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
title: "Custom",
|
||||||
|
onConfirm: () {
|
||||||
|
context.read<EffectPeriodBloc>().add(
|
||||||
|
SetCustomTime(selectedStartTime, selectedEndTime),
|
||||||
|
);
|
||||||
|
context.read<EffectPeriodBloc>().add(
|
||||||
|
const SetPeriod('Custom'),
|
||||||
|
);
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) => EffectPeriodBloc(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
BodyMedium(
|
||||||
|
text: 'Effective Period',
|
||||||
|
fontColor: ColorsManager.primaryColorWithOpacity,
|
||||||
|
fontWeight: FontsManager.bold,
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
color: ColorsManager.backgroundColor,
|
||||||
|
),
|
||||||
|
_buildPeriodOptions(context),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildRepeatDays(context),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPeriodOptions(BuildContext context) {
|
||||||
|
return BlocBuilder<EffectPeriodBloc, EffectPeriodState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
_buildRadioOption(context, 'All Day', '24 Hours'),
|
||||||
|
_buildRadioOption(context, 'Daytime', 'Sunrise to Sunset'),
|
||||||
|
_buildRadioOption(context, 'Night', 'Sunset to Sunrise'),
|
||||||
|
ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
onTap: () => showCustomTimePicker(context),
|
||||||
|
title: BodyMedium(
|
||||||
|
text: 'Custom',
|
||||||
|
fontColor: ColorsManager.primaryColorWithOpacity,
|
||||||
|
),
|
||||||
|
subtitle:
|
||||||
|
state.customStartTime != null && state.customEndTime != null
|
||||||
|
? BodySmall(
|
||||||
|
text:
|
||||||
|
'${"${state.customStartTime} AM"} - ${"${state.customEndTime} PM"}',
|
||||||
|
style: context.bodySmall.copyWith(fontSize: 10),
|
||||||
|
)
|
||||||
|
: BodySmall(
|
||||||
|
text: '00:00 AM - 11:59 PM',
|
||||||
|
style: context.bodySmall.copyWith(fontSize: 10),
|
||||||
|
),
|
||||||
|
trailing: Radio<String>(
|
||||||
|
value: 'Custom',
|
||||||
|
groupValue: state.selectedPeriod,
|
||||||
|
onChanged: (value) async {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRadioOption(
|
||||||
|
BuildContext context, String value, String subtitle) {
|
||||||
|
return BlocBuilder<EffectPeriodBloc, EffectPeriodState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
onTap: () {
|
||||||
|
context.read<EffectPeriodBloc>().add(SetPeriod(value));
|
||||||
|
},
|
||||||
|
title: BodyMedium(text: value),
|
||||||
|
subtitle: BodySmall(
|
||||||
|
text: subtitle,
|
||||||
|
style: context.bodySmall.copyWith(fontSize: 10),
|
||||||
|
),
|
||||||
|
trailing: Radio<String>(
|
||||||
|
value: value,
|
||||||
|
groupValue: state.selectedPeriod,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
context.read<EffectPeriodBloc>().add(SetPeriod(value));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRepeatDays(BuildContext context) {
|
||||||
|
final daysMap = {
|
||||||
|
'Mon': 'M',
|
||||||
|
'Tue': 'T',
|
||||||
|
'Wed': 'W',
|
||||||
|
'Thu': 'T',
|
||||||
|
'Fri': 'F',
|
||||||
|
'Sat': 'S',
|
||||||
|
'Sun': 'S',
|
||||||
|
};
|
||||||
|
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const BodyMedium(text: 'Repeat'),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
BlocBuilder<EffectPeriodBloc, EffectPeriodState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: daysMap.entries.map((entry) {
|
||||||
|
final day = entry.key;
|
||||||
|
final abbreviation = entry.value;
|
||||||
|
final isSelected = state.selectedDays.contains(day);
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 3.0),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
context.read<EffectPeriodBloc>().add(ToggleDay(day));
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color:
|
||||||
|
isSelected ? Colors.grey : Colors.grey.shade300,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: CircleAvatar(
|
||||||
|
radius: 15,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
child: Text(
|
||||||
|
abbreviation,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
color:
|
||||||
|
isSelected ? Colors.grey : Colors.grey.shade300,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ import 'package:syncrow_app/features/menu/view/widgets/profile/profile_view.dart
|
|||||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart';
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
|
||||||
import 'package:syncrow_app/features/scene/view/device_functions_view.dart';
|
import 'package:syncrow_app/features/scene/view/device_functions_view.dart';
|
||||||
|
import 'package:syncrow_app/features/scene/view/scene_auto_settings.dart';
|
||||||
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
|
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
|
||||||
import 'package:syncrow_app/features/scene/view/scene_rooms_tabbar.dart';
|
import 'package:syncrow_app/features/scene/view/scene_rooms_tabbar.dart';
|
||||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||||
@ -95,6 +96,11 @@ class Router {
|
|||||||
builder: (_) => DeviceFunctionsView(),
|
builder: (_) => DeviceFunctionsView(),
|
||||||
settings: settings,
|
settings: settings,
|
||||||
);
|
);
|
||||||
|
case Routes.sceneAutoSettingsRoute:
|
||||||
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const SceneAutoSettings(),
|
||||||
|
settings: settings,
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => Scaffold(
|
builder: (_) => Scaffold(
|
||||||
|
@ -19,6 +19,7 @@ class Routes {
|
|||||||
static const String createUnit = '/create-unit';
|
static const String createUnit = '/create-unit';
|
||||||
static const String sceneTasksRoute = '/scene-tasks';
|
static const String sceneTasksRoute = '/scene-tasks';
|
||||||
static const String sceneControlDevicesRoute = '/scene-control-devices';
|
static const String sceneControlDevicesRoute = '/scene-control-devices';
|
||||||
static const String deviceFunctionsRoute = '/device-functions';
|
static const String deviceFunctionsRoute = '/device-functions';
|
||||||
|
static const String sceneAutoSettingsRoute =
|
||||||
|
'/scene-automation-settings';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user