Solved conflicts and added latest update from routines design branch

This commit is contained in:
Abdullah Alassaf
2024-07-01 12:38:52 +03:00
8 changed files with 451 additions and 339 deletions

View File

@ -12,6 +12,7 @@ import 'package:syncrow_app/features/devices/model/create_temporary_password_mod
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
final String deviceId;
@ -30,8 +31,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
on<SelectTimeEvent>(selectTime);
on<DeletePasswordEvent>(deletePassword);
}
void _fetchSmartDoorStatus(
InitialEvent event, Emitter<SmartDoorState> emit) async {
void _fetchSmartDoorStatus(InitialEvent event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.getDeviceStatus(deviceId);
@ -47,24 +47,20 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
}
void getTemporaryPasswords(
InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
void getTemporaryPasswords(InitialPasswordsPage event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
pageType = event.type!;
var response = await DevicesAPI.getTemporaryPasswords(deviceId, pageType);
if (response is List) {
temporaryPasswords =
response.map((item) => TemporaryPassword.fromJson(item)).toList();
temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList();
} else if (response is Map && response.containsKey('data')) {
temporaryPasswords = (response['data'] as List)
.map((item) => TemporaryPassword.fromJson(item))
.toList();
temporaryPasswords =
(response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList();
} else {
throw Exception("Unexpected response format");
}
emit(TemporaryPasswordsLoadedState(
temporaryPassword: temporaryPasswords!));
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
}
@ -91,7 +87,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
} else {
endTime = event.val;
}
emit(changeTimeState());
emit(ChangeTimeState());
}
bool toggleRepeat(ToggleRepeatEvent event, Emitter<SmartDoorState> emit) {
@ -101,7 +97,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
return repeat;
}
bool setStartEndTime(SetStartEndTimeEvent event, Emitter<SmartDoorState> emit) {
emit(LoadingInitialState());
isStartEndTime = event.val;
@ -113,10 +108,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
emit(LoadingNewSate(smartDoorModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: deviceId,
code: 'normal_open_switch',
value: !event.value),
DeviceControlModel(deviceId: deviceId, code: 'normal_open_switch', value: !event.value),
deviceId);
if (response['success'] ?? false) {
@ -137,6 +129,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
Future<void> selectTime(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
emit(ChangeTimeState());
final DateTime? picked = await showDatePicker(
context: event.context,
initialDate: DateTime.now(),
@ -147,6 +140,22 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
final TimeOfDay? timePicked = await showTimePicker(
context: event.context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: const ColorScheme.light(
primary: ColorsManager.primaryColor,
onSurface: Colors.black,
),
buttonTheme: const ButtonThemeData(
colorScheme: ColorScheme.light(
primary: Colors.green,
),
),
),
child: child!,
);
},
);
if (timePicked != null) {
final selectedDateTime = DateTime(
@ -156,23 +165,31 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
timePicked.hour,
timePicked.minute,
);
// Convert selectedDateTime to a timestamp without seconds and milliseconds
final selectedTimestamp = DateTime(
selectedDateTime.year,
selectedDateTime.month,
selectedDateTime.day,
selectedDateTime.hour,
selectedDateTime.minute,
).millisecondsSinceEpoch ~/
1000; // Divide by 1000 to remove milliseconds
if (event.isEffective) {
if (expirationTimeTimeStamp != null &&
selectedDateTime.millisecondsSinceEpoch >
expirationTimeTimeStamp!) {
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
} else {
effectiveTime = selectedDateTime.toString();
effectiveTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
effectiveTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
effectiveTimeTimeStamp = selectedTimestamp;
}
} else {
if (effectiveTimeTimeStamp != null &&
selectedDateTime.millisecondsSinceEpoch <
effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Expiration Time cannot be earlier than Effective Time.');
} else {
expirationTime = selectedDateTime.toString();
expirationTimeTimeStamp = selectedDateTime.millisecondsSinceEpoch;
expirationTime =
selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
expirationTimeTimeStamp = selectedTimestamp;
}
}
emit(TimeSelectedState());
@ -183,8 +200,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
Future<void> savePassword(SavePasswordEvent event, Emitter<SmartDoorState> emit) async {
if (_validateInputs()) return;
try {
emit(LoadingSaveState());
var res = await DevicesAPI.createPassword(
emit(LoadingSaveState());
var res = await DevicesAPI.createPassword(
pageType: pageType,
deviceId: deviceId,
effectiveTime: effectiveTimeTimeStamp.toString(),
@ -200,20 +217,18 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
),
],
);
Navigator.of(event.context).pop(true);
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState());
} catch (_) {
}
Navigator.of(event.context).pop(true);
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState());
} catch (_) {}
}
Future<void> deletePassword(DeletePasswordEvent event, Emitter<SmartDoorState> emit) async {
try {
emit(LoadingInitialState());
var response = await DevicesAPI.deletePassword(
deviceId: deviceId, passwordId: event.passwordId)
.then((value) async {
var response =
await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId)
.then((value) async {
add(InitialPasswordsPage(type: pageType));
});
} catch (e) {
@ -222,7 +237,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
bool _validateInputs() {
if (passwordController.text.length<7) {
if (passwordController.text.length < 7) {
CustomSnackBar.displaySnackBar('Password less than 7');
return true;
}
@ -242,16 +257,13 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
CustomSnackBar.displaySnackBar('Select expiration time');
return true;
}
if (repeat == true &&
(endTime == null || startTime == null || selectedDay == null)) {
if (repeat == true && (endTime == null || startTime == null || selectedDay == null)) {
CustomSnackBar.displaySnackBar('Start Time and End time and the days required ');
return true;
}
return false;
}
List<DayInWeek> days = [
DayInWeek("S", dayKey: 'Sun'),
DayInWeek("M", dayKey: 'Mon'),
@ -266,5 +278,4 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
if (dateTime == null) return '';
return DateFormat('HH:mm').format(dateTime);
}
}

View File

@ -38,16 +38,25 @@ class FailedState extends SmartDoorState {
List<Object> get props => [errorMessage];
}
class GeneratePasswordState extends SmartDoorState{}
class TimeSelectedState extends SmartDoorState{}
class IsRepeatState extends SmartDoorState{}
class IsStartEndState extends SmartDoorState{}
class changeStartTimeState extends SmartDoorState{}
class changeEndTimeState extends SmartDoorState{}
class changeTimeState extends SmartDoorState{}
class SaveState extends SmartDoorState{}
class LoadingSaveState extends SmartDoorState{}
class TemporaryPasswordsLoadedState extends SmartDoorState{
final List<TemporaryPassword> temporaryPassword;
class GeneratePasswordState extends SmartDoorState {}
class TimeSelectedState extends SmartDoorState {}
class IsRepeatState extends SmartDoorState {}
class IsStartEndState extends SmartDoorState {}
class ChangeStartTimeState extends SmartDoorState {}
class ChangeEndTimeState extends SmartDoorState {}
class ChangeTimeState extends SmartDoorState {}
class SaveState extends SmartDoorState {}
class LoadingSaveState extends SmartDoorState {}
class TemporaryPasswordsLoadedState extends SmartDoorState {
final List<TemporaryPassword> temporaryPassword;
const TemporaryPasswordsLoadedState({required this.temporaryPassword});
}

View File

@ -19,13 +19,12 @@ class CreateTemporaryPassword extends StatelessWidget {
final String? deviceId;
final String? type;
const CreateTemporaryPassword({super.key,this.deviceId, this.type});
const CreateTemporaryPassword({super.key, this.deviceId, this.type});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
listener: (context, state) {
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
if (state is FailedState) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@ -34,291 +33,366 @@ class CreateTemporaryPassword extends StatelessWidget {
),
);
}
},
builder: (context, state) {
}, builder: (context, state) {
return DefaultScaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
title: const BodyLarge(
text: 'Create Password' ,
text: 'Create Password',
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
leading: IconButton(onPressed: () {
Navigator.of(context).pop('UpdatePage');
}, icon: const Icon(Icons.arrow_back)),
leading: IconButton(
onPressed: () {
Navigator.of(context).pop('UpdatePage');
},
icon: const Icon(Icons.arrow_back)),
actions: [
TextButton(
onPressed: () {
BlocProvider.of<SmartDoorBloc>(context).add(SavePasswordEvent(context: context));
BlocProvider.of<SmartDoorBloc>(context)
.add(SavePasswordEvent(context: context));
},
child: const Text('Save'))
],
),
child: state is LoadingInitialState?
const Center(child: CircularProgressIndicator()): SingleChildScrollView(
child:
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const BodyMedium(
text:
'Save the password immediately. The password is not displayed in the app.',
fontWeight: FontWeight.normal,
fontColor: ColorsManager.grayColor,
),
const SizedBox(
height: 20,
),
const BodyMedium(
text: '7-Digit Password',
fontWeight: FontWeight.normal,
fontColor: ColorsManager.grayColor,
),
DefaultContainer(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
child: Row(
child: state is LoadingInitialState
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: PinCodeTextField(
autoDisposeControllers: false,
keyboardType: TextInputType.phone,
length: 7,
enabled: true,
obscureText: false,
animationType: AnimationType.fade,
pinTheme: PinTheme(
shape: PinCodeFieldShape.underline,
fieldHeight: 45,
fieldWidth: 20,
activeFillColor: Colors.white,
disabledColor: Colors.grey,
activeColor: Colors.grey,
errorBorderColor: Colors.grey,
inactiveColor: Colors.grey,
inactiveFillColor: Colors.grey,
selectedColor: Colors.grey
),
animationDuration: Duration(milliseconds: 300),
backgroundColor: Colors.white,
enableActiveFill: false,
controller: BlocProvider.of<SmartDoorBloc>(context).passwordController,
appContext: context,
)),
const SizedBox(
width: 10,
const BodyMedium(
text:
'Save the password immediately. The password is not displayed in the app.',
fontWeight: FontWeight.normal,
fontColor: ColorsManager.grayColor,
),
InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context).add(GeneratePasswordEvent());
},
child: const BodyMedium(
text: 'Generate Randomly',
fontWeight: FontWeight.bold,
fontColor: ColorsManager.primaryColor,
))
],
),
),
BlocProvider.of<SmartDoorBloc>(context).passwordController.text.isNotEmpty?
TextButton(onPressed: () async {
await Clipboard.setData(ClipboardData(text: BlocProvider.of<SmartDoorBloc>(context).passwordController.text));
},
child: const Text('Copy')):SizedBox(),
const SizedBox(
height: 20,
),
DefaultContainer(
padding: const EdgeInsets.all(20),
child: Column(
children: [
ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: 'Password Name',
fontWeight: FontWeight.normal,
),
trailing: SizedBox(
width: MediaQuery.of(context).size.width / 2,
child: TextFormField(
controller:
BlocProvider.of<SmartDoorBloc>(context).passwordNameController,
decoration: const InputDecoration(
labelText: 'Enter The Name'),
)),
),
const Divider(color:Color(0xffEBEBEB),),
ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: 'Effective Time',
fontWeight: FontWeight.normal,
),
trailing: SizedBox(
width: MediaQuery.of(context).size.width / 2,
const SizedBox(
height: 20,
),
const BodyMedium(
text: '7-Digit Password',
fontWeight: FontWeight.normal,
fontColor: ColorsManager.grayColor,
),
DefaultContainer(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
flex: 2,
child: PinCodeTextField(
autoDisposeControllers: false,
keyboardType: TextInputType.phone,
length: 7,
enabled: true,
obscureText: false,
animationType: AnimationType.fade,
pinTheme: PinTheme(
shape: PinCodeFieldShape.underline,
fieldHeight: 45,
fieldWidth: 20,
activeFillColor: Colors.white,
disabledColor: Colors.grey,
activeColor: Colors.grey,
errorBorderColor: Colors.grey,
inactiveColor: Colors.grey,
inactiveFillColor: Colors.grey,
selectedColor: Colors.grey),
animationDuration: const Duration(milliseconds: 300),
backgroundColor: Colors.white,
enableActiveFill: false,
controller:
BlocProvider.of<SmartDoorBloc>(context).passwordController,
appContext: context,
)),
const SizedBox(
width: 10,
),
Flexible(
child: InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context)..add(SelectTimeEvent(context: context, isEffective: true));
// .selectTime(context, isEffective: true);
},
child: Text(
BlocProvider.of<SmartDoorBloc>(context).effectiveTime
),
)),
),
const Divider(color:Color(0xffEBEBEB),),
ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: 'Expiration Time',
fontWeight: FontWeight.normal,
),
trailing: SizedBox(
width: MediaQuery.of(context).size.width / 2,
child: SizedBox(
width: MediaQuery.of(context).size.width / 2,
child: InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context)..add(SelectTimeEvent(context: context, isEffective: false));
// BlocProvider.of<SmartDoorBloc>(context)
// .selectTime(context,
// isEffective: false);
BlocProvider.of<SmartDoorBloc>(context)
.add(GeneratePasswordEvent());
},
child: Text(
BlocProvider.of<SmartDoorBloc>(context)
.expirationTime),
child: const BodyMedium(
text: 'Generate Randomly',
fontWeight: FontWeight.bold,
fontColor: ColorsManager.primaryColor,
)),
)
],
),
),
BlocProvider.of<SmartDoorBloc>(context).passwordController.text.isNotEmpty
? TextButton(
onPressed: () async {
await Clipboard.setData(ClipboardData(
text: BlocProvider.of<SmartDoorBloc>(context)
.passwordController
.text));
},
child: const Text('Copy'))
: const SizedBox(),
const SizedBox(
height: 20,
),
DefaultContainer(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
padding: const EdgeInsets.all(10.0),
child: const BodyMedium(
text: 'Password Name',
fontWeight: FontWeight.normal,
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width / 2.6,
child: TextFormField(
controller: BlocProvider.of<SmartDoorBloc>(context)
.passwordNameController,
decoration: const InputDecoration(
hintText: 'Enter The Name',
hintStyle: TextStyle(
fontSize: 14, color: ColorsManager.textGray)),
)),
],
),
const Divider(
color: ColorsManager.graysColor,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Expanded(
child: BodyMedium(
text: 'Effective Time',
fontWeight: FontWeight.normal,
),
),
SizedBox(
width: MediaQuery.of(context).size.width / 3.5,
child: InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context).add(
SelectTimeEvent(
context: context, isEffective: true));
},
child: Text(
BlocProvider.of<SmartDoorBloc>(context).effectiveTime,
style: TextStyle(
fontSize: 14,
color: BlocProvider.of<SmartDoorBloc>(context)
.effectiveTime ==
'Select Time'
? ColorsManager.textGray
: null),
),
)),
],
),
),
const Divider(
color: ColorsManager.graysColor,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Expanded(
child: BodyMedium(
text: 'Expiration Time',
fontWeight: FontWeight.normal,
),
),
SizedBox(
width: MediaQuery.of(context).size.width / 3.5,
child: InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context).add(
SelectTimeEvent(
context: context, isEffective: false));
},
child: Text(
BlocProvider.of<SmartDoorBloc>(context).expirationTime,
style: TextStyle(
fontSize: 14,
color: BlocProvider.of<SmartDoorBloc>(context)
.expirationTime ==
'Select Time'
? ColorsManager.textGray
: null),
),
),
),
],
),
),
],
)),
const SizedBox(
height: 20,
),
if (type == 'Online Password')
DefaultContainer(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: 'Repeat',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: BlocProvider.of<SmartDoorBloc>(context).repeat,
onChanged: (value) {
BlocProvider.of<SmartDoorBloc>(context)
.add(ToggleRepeatEvent());
},
applyTheme: true,
)),
),
),
],
)),
const SizedBox(
height: 20,
),
if(type=='Online Password')
DefaultContainer(
padding:
const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: 'Repeat',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value:
BlocProvider.of<SmartDoorBloc>(context).repeat,
onChanged: (value) {
BlocProvider.of<SmartDoorBloc>(context).add(ToggleRepeatEvent());
},
applyTheme: true,
)),
const SizedBox(
height: 20,
),
BlocProvider.of<SmartDoorBloc>(context).repeat
? DefaultContainer(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context)
.add(const SetStartEndTimeEvent(val: true));
},
child: BodyMedium(
text: 'Start',
fontColor: BlocProvider.of<SmartDoorBloc>(context)
.isStartEndTime ==
false
? Colors.black
: Colors.blue,
fontSize: 18,
),
),
InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context)
.add(const SetStartEndTimeEvent(val: false));
},
child: BodyMedium(
text: 'End',
fontColor: BlocProvider.of<SmartDoorBloc>(context)
.isStartEndTime
? Colors.black
: Colors.blue,
fontSize: 18,
),
)
],
),
),
const Divider(
color: ColorsManager.graysColor,
),
Container(
height: 110,
child: BlocProvider.of<SmartDoorBloc>(context).isStartEndTime
? TimePickerSpinner(
time:
BlocProvider.of<SmartDoorBloc>(context).startTime,
is24HourMode: false,
itemHeight: 40,
normalTextStyle: const TextStyle(
color: Colors.grey,
fontSize: 24,
),
highlightedTextStyle:
const TextStyle(fontSize: 30, color: Colors.blue),
onTimeChange: (time) {
BlocProvider.of<SmartDoorBloc>(context).add(
ChangeTimeEvent(
val: time,
isStartEndTime:
BlocProvider.of<SmartDoorBloc>(context)
.isStartEndTime));
},
)
: Container(
child: TimePickerSpinner(
time:
BlocProvider.of<SmartDoorBloc>(context).endTime,
is24HourMode: false,
itemHeight: 40,
normalTextStyle: const TextStyle(
color: Colors.grey,
fontSize: 24,
),
highlightedTextStyle: const TextStyle(
fontSize: 30, color: Colors.blue),
onTimeChange: (time) {
BlocProvider.of<SmartDoorBloc>(context).add(
ChangeTimeEvent(
val: time,
isStartEndTime:
BlocProvider.of<SmartDoorBloc>(
context)
.isStartEndTime));
},
),
),
),
const Divider(
color: ColorsManager.graysColor,
),
const SizedBox(height: 20),
SelectWeekDays(
width: MediaQuery.of(context).size.width / 1,
fontSize: 18,
fontWeight: FontWeight.w600,
days: BlocProvider.of<SmartDoorBloc>(context).days,
border: false,
selectedDayTextColor: Colors.black,
unSelectedDayTextColor: Colors.grey,
boxDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Colors.white),
onSelect: (values) {
BlocProvider.of<SmartDoorBloc>(context).selectedDay =
values;
},
),
],
))
: const SizedBox(),
const SizedBox(
height: 40,
)
],
),
),
const SizedBox(
height: 20,
),
BlocProvider.of<SmartDoorBloc>(context).repeat
? DefaultContainer(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 5),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context).add(const SetStartEndTimeEvent(val: true));
},
child: BodyMedium(text: 'Start',fontColor:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime==false? Colors.black:Colors.blue,fontSize: 18,),
),
InkWell(
onTap: () {
BlocProvider.of<SmartDoorBloc>(context).add(const SetStartEndTimeEvent(val: false));
},
child: BodyMedium(text: 'End',fontColor:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime? Colors.black:Colors.blue,fontSize: 18,),
)
],
),
),
const Divider(color:Color(0xffEBEBEB),),
Container(
height: 80,
child:
Container(
height: 90,
child:BlocProvider.of<SmartDoorBloc>(context).isStartEndTime? TimePickerSpinner(
time:
BlocProvider.of<SmartDoorBloc>(context).startTime,
is24HourMode: false,
itemHeight: 40,
normalTextStyle: const TextStyle(
fontSize: 24,
),
highlightedTextStyle: const TextStyle(
fontSize: 30, color: Colors.blue),
onTimeChange: (time) {
// BlocProvider.of<SmartDoorBloc>(context).changeTime(time, BlocProvider.of<SmartDoorBloc>(context).isStartEndTime);
BlocProvider.of<SmartDoorBloc>(context).add(ChangeTimeEvent(val: time, isStartEndTime: BlocProvider.of<SmartDoorBloc>(context).isStartEndTime));
},
): Container(
child: TimePickerSpinner(
time: BlocProvider.of<SmartDoorBloc>(context).endTime,
is24HourMode: false,
itemHeight: 40,
normalTextStyle: const TextStyle(
fontSize: 24,
),
highlightedTextStyle: const TextStyle(
fontSize: 30, color: Colors.blue),
onTimeChange: (time) {
BlocProvider.of<SmartDoorBloc>(context).add(ChangeTimeEvent(val: time, isStartEndTime: BlocProvider.of<SmartDoorBloc>(context).isStartEndTime));
// BlocProvider.of<SmartDoorBloc>(context).changeTime(time, BlocProvider.of<SmartDoorBloc>(context).isStartEndTime);
},
),
),
)
),
const Divider(color:Color(0xffEBEBEB),),
const SizedBox(height: 20),
SelectWeekDays(
width: MediaQuery.of(context).size.width / 1,
fontSize: 18,
fontWeight: FontWeight.w600,
days: BlocProvider.of<SmartDoorBloc>(context)
.days,
border: false,
selectedDayTextColor: Colors.black,
unSelectedDayTextColor: Colors.grey,
boxDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Colors.white),
onSelect: (values) {
BlocProvider.of<SmartDoorBloc>(context).selectedDay = values;
},
),
],
))
: SizedBox(),
const SizedBox(
height: 40,
)
],
),
),
);
}));
}

View File

@ -32,10 +32,15 @@ class DoorDialogState extends State<DoorDialog> {
@override
Widget build(BuildContext context) {
final DateTime effectiveDateTime =
DateTime.fromMillisecondsSinceEpoch(widget.value.effectiveTime);
DateTime.fromMillisecondsSinceEpoch(widget.value.effectiveTime * 1000, isUtc: true);
String formattedDateEffectiveTime = DateFormat('yyyy-MM-dd').format(effectiveDateTime);
String formattedTimeEffectiveTime = DateFormat('HH:mm:ss').format(effectiveDateTime);
final DateTime expiredDateTime =
DateTime.fromMillisecondsSinceEpoch(widget.value.invalidTime);
final DateFormat formatter = DateFormat('HH:mm');
DateTime.fromMillisecondsSinceEpoch(widget.value.invalidTime * 1000, isUtc: true);
String formattedDateExpiredDateTime = DateFormat('yyyy-MM-dd').format(expiredDateTime);
String formattedTimeExpiredDateTime = DateFormat('HH:mm:ss').format(expiredDateTime);
return Dialog(
child: Container(
decoration: BoxDecoration(
@ -73,15 +78,32 @@ class DoorDialogState extends State<DoorDialog> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Effective Time :'),
Text(formatter.format(effectiveDateTime)),
const Text('Effective Date:'),
Text(formattedDateEffectiveTime),
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Expired Time :'),
Text(formatter.format(expiredDateTime)),
const Text('Effective Time:'),
Text(formattedTimeEffectiveTime),
],
),
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Expired Date:'),
Text(formattedDateExpiredDateTime),
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Expired Time:'),
Text(formattedTimeExpiredDateTime),
],
),
],
@ -102,8 +124,7 @@ class DoorDialogState extends State<DoorDialog> {
child: Center(
child: BodyMedium(
text: 'Cancel',
style: context.bodyMedium
.copyWith(color: ColorsManager.greyColor),
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
),
),
),
@ -115,13 +136,11 @@ class DoorDialogState extends State<DoorDialog> {
InkWell(
onTap: () {
Navigator.pop(context, 'delete');
},
child: Center(
child: BodyMedium(
text: 'Delete Password',
style: context.bodyMedium.copyWith(
color: ColorsManager.primaryColorWithOpacity),
style: context.bodyMedium.copyWith(color: ColorsManager.primaryColorWithOpacity),
),
),
),

View File

@ -96,7 +96,7 @@ class TemporaryPasswordPage extends StatelessWidget {
),
),
const Divider( ),
const Divider(color:ColorsManager.graysColor,),
ListTile(
contentPadding: EdgeInsets.zero,
leading: SvgPicture.asset(

View File

@ -15,8 +15,7 @@ import 'package:syncrow_app/utils/context_extension.dart';
mixin SceneLogicHelper {
bool isOnlyDelayOrDelayLast(List<SceneStaticFunction> tasks) {
final lastTask = tasks.last;
return tasks.every((task) => task.code == 'delay') ||
lastTask.code == 'delay';
return tasks.every((task) => task.code == 'delay') || lastTask.code == 'delay';
}
void handleSaveButtonPress(
@ -122,8 +121,7 @@ mixin SceneLogicHelper {
);
} else {
return AlertDialogCountdown(
durationValue: listOfSceneStaticFunction[index].functionValue ??
taskItem.functionValue,
durationValue: listOfSceneStaticFunction[index].functionValue ?? taskItem.functionValue,
functionValue: taskItem.functionValue,
function: listOfSceneStaticFunction[index],
);

View File

@ -5,8 +5,7 @@ abstract class ColorsManager {
static const Color switchOffColor = Color(0x7F8D99AE);
static const Color primaryColor = Color(0xFF0030CB);
static const Color secondaryTextColor = Color(0xFF848484);
static Color primaryColorWithOpacity =
const Color(0xFF023DFE).withOpacity(0.6);
static Color primaryColorWithOpacity = const Color(0xFF023DFE).withOpacity(0.6);
static const Color onPrimaryColor = Colors.white;
static const Color secondaryColor = Color(0xFF023DFE);
static const Color onSecondaryColor = Color(0xFF023DFE);
@ -26,4 +25,6 @@ abstract class ColorsManager {
static const Color lightGreen = Color(0xFF00FF0A);
static const Color grayColor = Color(0xFF999999);
static const Color red = Colors.red;
static const Color graysColor = Color(0xffEBEBEB);
static const Color textGray = Color(0xffD5D5D5);
}

View File

@ -5,7 +5,7 @@ description: This is the mobile application project, developed with Flutter for
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.5+7
version: 1.0.8+9
environment:
sdk: ">=3.0.6 <4.0.0"