mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-11-26 08:54:54 +00:00
Merge pull request #45 from SyncrowIOT/fix_bugs_doorlock_qa
fix password
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
|
||||||
@ -12,6 +13,7 @@ import 'package:syncrow_app/features/devices/model/smart_door_model.dart';
|
|||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/create_temporary_password_model.dart';
|
import 'package:syncrow_app/features/devices/model/create_temporary_password_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
|
import 'package:syncrow_app/features/devices/model/temporary_password_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/hour_picker_dialog.dart';
|
||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
@ -32,7 +34,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
on<SetStartEndTimeEvent>(setStartEndTime);
|
on<SetStartEndTimeEvent>(setStartEndTime);
|
||||||
on<ChangeTimeEvent>(changeTime);
|
on<ChangeTimeEvent>(changeTime);
|
||||||
on<GeneratePasswordEvent>(generate7DigitNumber);
|
on<GeneratePasswordEvent>(generate7DigitNumber);
|
||||||
on<SelectTimeEvent>(selectTime);
|
on<SelectTimeEvent>(selectTimeOfLinePassword);
|
||||||
|
on<SelectTimeOnlinePasswordEvent>(selectTimeOnlinePassword);
|
||||||
on<DeletePasswordEvent>(deletePassword);
|
on<DeletePasswordEvent>(deletePassword);
|
||||||
on<GenerateAndSavePasswordTimeLimitEvent>(generateAndSavePasswordTimeLimited);
|
on<GenerateAndSavePasswordTimeLimitEvent>(generateAndSavePasswordTimeLimited);
|
||||||
on<GenerateAndSavePasswordOneTimeEvent>(generateAndSavePasswordOneTime);
|
on<GenerateAndSavePasswordOneTimeEvent>(generateAndSavePasswordOneTime);
|
||||||
@ -66,7 +69,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
return passwordController.text;
|
return passwordController.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future generateAndSavePasswordOneTime (GenerateAndSavePasswordOneTimeEvent event, Emitter<SmartDoorState> emit) async {
|
Future generateAndSavePasswordOneTime (GenerateAndSavePasswordOneTimeEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
try {
|
try {
|
||||||
if (isSavingPassword) return;
|
if (isSavingPassword) return;
|
||||||
@ -76,6 +78,10 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
ApiResponse pass= ApiResponse.fromJson(res);
|
ApiResponse pass= ApiResponse.fromJson(res);
|
||||||
passwordController.text =pass.data.offlineTempPassword;
|
passwordController.text =pass.data.offlineTempPassword;
|
||||||
passwordId=pass.data.offlineTempPasswordId;
|
passwordId=pass.data.offlineTempPasswordId;
|
||||||
|
|
||||||
|
Future.delayed(const Duration(seconds: 1), () {
|
||||||
|
Clipboard.setData(ClipboardData(text: passwordController.text));
|
||||||
|
});
|
||||||
emit(const GeneratePasswordOneTimestate(generated: true));
|
emit(const GeneratePasswordOneTimestate(generated: true));
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
emit(FailedState(errorMessage: _.toString()));
|
emit(FailedState(errorMessage: _.toString()));
|
||||||
@ -108,6 +114,8 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
doorLockUuid:deviceId ,
|
doorLockUuid:deviceId ,
|
||||||
passwordId:passwordId
|
passwordId:passwordId
|
||||||
);
|
);
|
||||||
|
add(InitialOneTimePassword());
|
||||||
|
add(InitialTimeLimitPassword());
|
||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
@ -150,6 +158,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
if (response is List) {
|
if (response is List) {
|
||||||
timeLimitPasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
|
timeLimitPasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
emit(FailedState(errorMessage: e.toString()));
|
||||||
@ -192,7 +201,56 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
emit(UpdateState(smartDoorModel: deviceStatus));
|
emit(UpdateState(smartDoorModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> selectTime(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
|
||||||
|
Future<void> selectTimeOfLinePassword(SelectTimeEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
|
emit(ChangeTimeState());
|
||||||
|
final DateTime? picked = await showDatePicker(
|
||||||
|
context: event.context,
|
||||||
|
initialDate: DateTime.now(),
|
||||||
|
firstDate: DateTime.now(),
|
||||||
|
lastDate: DateTime(2101),
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
final TimeOfDay? timePicked = await showHourPicker(
|
||||||
|
context: event.context,
|
||||||
|
initialTime: TimeOfDay.now(),
|
||||||
|
);
|
||||||
|
if (timePicked != null) {
|
||||||
|
final selectedDateTime = DateTime(
|
||||||
|
picked.year,
|
||||||
|
picked.month,
|
||||||
|
picked.day,
|
||||||
|
timePicked.hour,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
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 && selectedTimestamp > expirationTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
|
||||||
|
} else {
|
||||||
|
effectiveTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||||
|
effectiveTimeTimeStamp = selectedTimestamp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
|
||||||
|
} else {
|
||||||
|
expirationTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||||
|
expirationTimeTimeStamp = selectedTimestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(TimeSelectedState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> selectTimeOnlinePassword(SelectTimeOnlinePasswordEvent event, Emitter<SmartDoorState> emit) async {
|
||||||
emit(ChangeTimeState());
|
emit(ChangeTimeState());
|
||||||
final DateTime? picked = await showDatePicker(
|
final DateTime? picked = await showDatePicker(
|
||||||
context: event.context,
|
context: event.context,
|
||||||
@ -294,16 +352,22 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
try {
|
try {
|
||||||
isSavingPassword = true;
|
isSavingPassword = true;
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
var res = await DevicesAPI.generateMultiTimePassword(deviceId: deviceId,
|
var res = await DevicesAPI.generateMultiTimePassword(
|
||||||
|
deviceId: deviceId,
|
||||||
effectiveTime: effectiveTimeTimeStamp.toString(),
|
effectiveTime: effectiveTimeTimeStamp.toString(),
|
||||||
invalidTime: expirationTimeTimeStamp.toString(), );
|
invalidTime: expirationTimeTimeStamp.toString(),
|
||||||
|
);
|
||||||
ApiResponse pass= ApiResponse.fromJson(res);
|
ApiResponse pass= ApiResponse.fromJson(res);
|
||||||
passwordController.text =pass.data.offlineTempPassword;
|
passwordController.text =pass.data.offlineTempPassword;
|
||||||
passwordId=pass.data.offlineTempPasswordId;
|
passwordId=pass.data.offlineTempPasswordId;
|
||||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||||
|
add(InitialTimeLimitPassword());
|
||||||
|
Future.delayed(const Duration(seconds: 1), () {
|
||||||
|
Clipboard.setData(ClipboardData(text: passwordController.text));
|
||||||
|
});
|
||||||
emit(const GeneratePasswordOneTimestate(generated: true));
|
emit(const GeneratePasswordOneTimestate(generated: true));
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
emit(FailedState(errorMessage: e.toString()));
|
add(InitialPasswordsPage());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
isSavingPassword = false;
|
isSavingPassword = false;
|
||||||
@ -328,6 +392,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
CustomSnackBar.displaySnackBar('Password less than 7');
|
CustomSnackBar.displaySnackBar('Password less than 7');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (passwordController.text.isEmpty) {
|
if (passwordController.text.isEmpty) {
|
||||||
CustomSnackBar.displaySnackBar('Password required');
|
CustomSnackBar.displaySnackBar('Password required');
|
||||||
return true;
|
return true;
|
||||||
@ -336,20 +401,24 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
CustomSnackBar.displaySnackBar('Password name required');
|
CustomSnackBar.displaySnackBar('Password name required');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
||||||
CustomSnackBar.displaySnackBar('Select effective time');
|
CustomSnackBar.displaySnackBar('Select effective time');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expirationTime == 'Select Time' || expirationTimeTimeStamp == null) {
|
if (expirationTime == 'Select Time' || expirationTimeTimeStamp == null) {
|
||||||
CustomSnackBar.displaySnackBar('Select expiration time');
|
CustomSnackBar.displaySnackBar('Select expiration time');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repeat == true && (endTime == null || startTime == null || selectedDays == null)) {
|
if (repeat == true && (endTime == null || startTime == null || selectedDays == null)) {
|
||||||
CustomSnackBar.displaySnackBar('Start Time and End time and the days required ');
|
CustomSnackBar.displaySnackBar('Start Time and End time and the days required ');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool timeLimitValidate() {
|
bool timeLimitValidate() {
|
||||||
|
|
||||||
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
if (effectiveTime == 'Select Time' || effectiveTimeTimeStamp == null) {
|
||||||
@ -392,3 +461,6 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,14 @@ class SelectTimeEvent extends SmartDoorEvent {
|
|||||||
List<Object> get props => [context,isEffective];
|
List<Object> get props => [context,isEffective];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SelectTimeOnlinePasswordEvent extends SmartDoorEvent {
|
||||||
|
final BuildContext context;
|
||||||
|
final bool isEffective;
|
||||||
|
const SelectTimeOnlinePasswordEvent({required this.context,required this.isEffective});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [context,isEffective];
|
||||||
|
}
|
||||||
|
|
||||||
class ToggleRepeatEvent extends SmartDoorEvent {}
|
class ToggleRepeatEvent extends SmartDoorEvent {}
|
||||||
class SetStartEndTimeEvent extends SmartDoorEvent {
|
class SetStartEndTimeEvent extends SmartDoorEvent {
|
||||||
final bool val;
|
final bool val;
|
||||||
|
|||||||
92
lib/features/devices/view/widgets/hour_picker_dialog.dart
Normal file
92
lib/features/devices/view/widgets/hour_picker_dialog.dart
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class HourPickerDialog extends StatefulWidget {
|
||||||
|
final TimeOfDay initialTime;
|
||||||
|
HourPickerDialog({required this.initialTime});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_HourPickerDialogState createState() => _HourPickerDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HourPickerDialogState extends State<HourPickerDialog> {
|
||||||
|
late int _selectedHour;
|
||||||
|
bool _isPm = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_selectedHour = widget.initialTime.hour > 12 ? widget.initialTime.hour - 12 : widget.initialTime.hour;
|
||||||
|
_isPm = widget.initialTime.period == DayPeriod.pm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text('Select Hour'),
|
||||||
|
content: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
DropdownButton<int>(
|
||||||
|
value: _selectedHour,
|
||||||
|
items: List.generate(12, (index) {
|
||||||
|
int displayHour = index + 1;
|
||||||
|
return DropdownMenuItem(
|
||||||
|
value: displayHour,
|
||||||
|
child: Text(displayHour.toString()),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_selectedHour = value!;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(width: 16.0),
|
||||||
|
DropdownButton<bool>(
|
||||||
|
value: _isPm,
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: false,
|
||||||
|
child: Text('AM'),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: true,
|
||||||
|
child: Text('PM'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_isPm = value!;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(null),
|
||||||
|
child: Text('Cancel'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
int hour = _isPm ? _selectedHour + 12 : _selectedHour;
|
||||||
|
Navigator.of(context).pop(TimeOfDay(hour: hour, minute: 0));
|
||||||
|
},
|
||||||
|
child: Text('OK'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<TimeOfDay?> showHourPicker({
|
||||||
|
required BuildContext context,
|
||||||
|
required TimeOfDay initialTime,
|
||||||
|
}) {
|
||||||
|
return showDialog<TimeOfDay>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => HourPickerDialog(initialTime: initialTime),
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -60,7 +60,7 @@ class NameTimeWidget extends StatelessWidget {
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
||||||
BlocProvider.of<SmartDoorBloc>(context).add(SelectTimeEvent(context: context, isEffective: true));
|
BlocProvider.of<SmartDoorBloc>(context).add(SelectTimeOnlinePasswordEvent(context: context, isEffective: true));
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
BlocProvider.of<SmartDoorBloc>(context).effectiveTime,
|
BlocProvider.of<SmartDoorBloc>(context).effectiveTime,
|
||||||
@ -92,7 +92,7 @@ class NameTimeWidget extends StatelessWidget {
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<SmartDoorBloc>(context).add(
|
BlocProvider.of<SmartDoorBloc>(context).add(
|
||||||
SelectTimeEvent(
|
SelectTimeOnlinePasswordEvent(
|
||||||
context: context, isEffective: false));
|
context: context, isEffective: false));
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
|||||||
import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart';
|
import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
@ -28,11 +29,8 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
|
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
|
||||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
|
||||||
if (state is FailedState) {
|
if (state is FailedState) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
SnackBar(
|
state.errorMessage
|
||||||
content: Text(state.errorMessage),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (state is IsRepeatState){
|
if (state is IsRepeatState){
|
||||||
@ -104,6 +102,7 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BodyLarge(
|
child: BodyLarge(
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@ -114,8 +113,9 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
wordSpacing: 2),
|
wordSpacing: 2),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
text: smartDoorBloc.passwordController.text,
|
text: smartDoorBloc.passwordController.text,
|
||||||
fontSize: 25,
|
fontSize: 23,
|
||||||
),),
|
),),
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Clipboard.setData(ClipboardData(
|
await Clipboard.setData(ClipboardData(
|
||||||
@ -166,7 +166,6 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -195,9 +194,6 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if(generated==false){
|
if(generated==false){
|
||||||
smartDoorBloc.add(GenerateAndSavePasswordOneTimeEvent(context: context));
|
smartDoorBloc.add(GenerateAndSavePasswordOneTimeEvent(context: context));
|
||||||
await Clipboard.setData(
|
|
||||||
ClipboardData(text: smartDoorBloc.passwordController.text)
|
|
||||||
);
|
|
||||||
}else{
|
}else{
|
||||||
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
||||||
smartDoorBloc.add(RenamePasswordEvent());
|
smartDoorBloc.add(RenamePasswordEvent());
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
|||||||
import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart';
|
import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
@ -27,11 +28,8 @@ class CreateOfflineTimeLimitPasswordPage extends StatelessWidget {
|
|||||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is FailedState) {
|
if (state is FailedState) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
SnackBar(
|
state.errorMessage
|
||||||
content: Text(state.errorMessage),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (state is IsRepeatState) {
|
if (state is IsRepeatState) {
|
||||||
@ -240,8 +238,7 @@ class CreateOfflineTimeLimitPasswordPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const BodyMedium(
|
const BodyMedium(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
text:
|
text: 'Use the time-limited password at least once within 24 hours after the password takes effect. Otherwise, the password becomes invalid.',
|
||||||
'Use the time-limited password at least once within 24 hours after the password takes effect. Otherwise, the password becomes invalid.',
|
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontColor: ColorsManager.grayColor,
|
fontColor: ColorsManager.grayColor,
|
||||||
),
|
),
|
||||||
@ -259,14 +256,10 @@ class CreateOfflineTimeLimitPasswordPage extends StatelessWidget {
|
|||||||
backgroundColor: ColorsManager.primaryColor,
|
backgroundColor: ColorsManager.primaryColor,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (generated == false) {
|
if (generated == false) {
|
||||||
smartDoorBloc.add(
|
smartDoorBloc.add(GenerateAndSavePasswordTimeLimitEvent(context: context));
|
||||||
GenerateAndSavePasswordTimeLimitEvent(context: context));
|
|
||||||
await Clipboard.setData(
|
|
||||||
ClipboardData(text: smartDoorBloc.passwordController.text)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
if(smartDoorBloc.passwordNameController.text.isNotEmpty){
|
||||||
smartDoorBloc.add(RenamePasswordEvent());
|
smartDoorBloc.add(RenamePasswordEvent());
|
||||||
}
|
}
|
||||||
Navigator.of(context).pop(true);
|
Navigator.of(context).pop(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
|||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'door_dialog.dart';
|
import 'door_dialog.dart';
|
||||||
|
|
||||||
@ -22,11 +23,8 @@ class TimeLimitedPasswordPage extends StatelessWidget {
|
|||||||
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is FailedState) {
|
if (state is FailedState) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
SnackBar(
|
state.errorMessage
|
||||||
content: Text(state.errorMessage),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -40,10 +38,8 @@ class TimeLimitedPasswordPage extends StatelessWidget {
|
|||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(builder: (context) => CreateOfflineTimeLimitPasswordPage(deviceId: deviceId,)
|
MaterialPageRoute(builder: (context) => CreateOfflineTimeLimitPasswordPage(deviceId: deviceId,)
|
||||||
)).then((result) {
|
)).then((result) {
|
||||||
if (result != null) {
|
smartDoorBloc.add(InitialTimeLimitPassword());
|
||||||
smartDoorBloc.add(InitialTimeLimitPassword());
|
smartDoorBloc.add(InitialTimeLimitPassword());
|
||||||
smartDoorBloc.add(InitialTimeLimitPassword());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add)
|
icon: const Icon(Icons.add)
|
||||||
|
|||||||
@ -197,13 +197,13 @@ class DevicesAPI {
|
|||||||
required String invalidTime,
|
required String invalidTime,
|
||||||
required String deviceId,
|
required String deviceId,
|
||||||
List<Schedule>? scheduleList,}) async {
|
List<Schedule>? scheduleList,}) async {
|
||||||
|
|
||||||
Map<String, dynamic> body = {
|
Map<String, dynamic> body = {
|
||||||
"name": name,
|
"name": name,
|
||||||
"password": password,
|
"password": password,
|
||||||
"effectiveTime": effectiveTime,
|
"effectiveTime": effectiveTime,
|
||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
};
|
};
|
||||||
|
print('createPassword =$body');
|
||||||
if (scheduleList != null) {
|
if (scheduleList != null) {
|
||||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ class DevicesAPI {
|
|||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: true,
|
||||||
body: {
|
body: {
|
||||||
"effectiveTime": effectiveTime,
|
"effectiveTime": effectiveTime,
|
||||||
"invalidTime": invalidTime
|
"invalidTime": invalidTime
|
||||||
|
|||||||
Reference in New Issue
Block a user