mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-03-11 02:51:44 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| acc4e06010 | |||
| f5eaf8ab24 |
@ -1,5 +0,0 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555643 0.555643 0 1.24111 0H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79675 39.5036 2.48221L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
|
||||
<path d="M38.7589 0H35.0356C35.721 0 36.2767 0.555643 36.2767 1.24111V38.7589C36.2767 39.4444 35.721 40 35.0356 40H38.7589C39.4444 40 40 39.4444 40 38.7589V1.24111C40 0.555643 39.4444 0 38.7589 0Z" fill="#D1D1D1"/>
|
||||
<path opacity="0.6" d="M21.375 31.8319V33.3213C21.375 34.0067 20.9553 34.5624 20.4375 34.5624H16.3125C15.7947 34.5624 15.375 34.0067 15.375 33.3213V31.8319C15.375 31.1465 15.7947 30.5908 16.3125 30.5908H20.4375C20.9553 30.5908 21.375 31.1465 21.375 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 933 B |
@ -1,7 +0,0 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555643 0.555643 0 1.24111 0H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79675 39.5036 2.48221L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
|
||||
<path d="M38.7589 0H35.0356C35.721 0 36.2767 0.555643 36.2767 1.24111V38.7589C36.2767 39.4444 35.721 40 35.0356 40H38.7589C39.4444 40 40 39.4444 40 38.7589V1.24111C40 0.555643 39.4444 0 38.7589 0Z" fill="#D1D1D1"/>
|
||||
<path opacity="0.6" d="M12.0284 31.8319V33.3213C12.0284 34.0067 11.6087 34.5624 11.0909 34.5624H6.96594C6.44816 34.5624 6.02844 34.0067 6.02844 33.3213V31.8319C6.02844 31.1465 6.44816 30.5908 6.96594 30.5908H11.0909C11.6087 30.5908 12.0284 31.1465 12.0284 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
<path opacity="0.6" d="M26.0285 31.8319V33.3213C26.0285 34.0067 26.4482 34.5624 26.966 34.5624H31.091C31.6088 34.5624 32.0285 34.0067 32.0285 33.3213V31.8319C32.0285 31.1465 31.6088 30.5908 31.091 30.5908H26.966C26.4482 30.5908 26.0285 31.1465 26.0285 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
<path d="M19.0691 0H20.9308V40H19.0691V0Z" fill="#D1D1D1"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1,15 +0,0 @@
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.5419 20.2425C11.1182 19.3486 10.0545 18.9679 9.16647 19.3936L1.38334 23.1269C0.591819 23.3099 0 24.0198 0 24.8727V33.8466C0 34.8381 0.797668 35.6414 1.78229 35.6414C2.76668 35.6414 3.56412 34.8381 3.56412 33.8466V27.6645L9.16647 30.3517C9.41376 30.4705 9.67449 30.5264 9.93112 30.5264C10.5974 30.5264 11.2359 30.1484 11.5419 29.5026C11.9643 28.6076 11.5875 27.5367 10.699 27.1104L6.03295 24.8725L10.699 22.6347C11.5877 22.2085 11.9643 21.1376 11.5419 20.2425Z" fill="#D5D5D5"/>
|
||||
<path d="M20.6084 17.6893C20.8655 17.6893 21.1257 17.6334 21.3737 17.5145L32.0481 12.395C32.9366 11.9684 33.3141 10.8973 32.891 10.0024C32.4682 9.10855 31.4052 8.72804 30.5156 9.1535L19.8408 14.2735C18.9522 14.6999 18.5754 15.7705 18.998 16.6657C19.3038 17.3111 19.9423 17.6893 20.6084 17.6893Z" fill="#D5D5D5"/>
|
||||
<path d="M42.7227 7.27445L48.1841 4.65449V10.9114C48.1841 11.9027 48.9818 12.7061 49.9659 12.7061C50.9503 12.7061 51.7478 11.9027 51.7478 10.9114V4.62192L57.2779 7.27445C57.5259 7.39303 57.7862 7.44922 58.0433 7.44922C58.7091 7.44922 59.3478 7.07124 59.6534 6.42537C60.0763 5.53041 59.6994 4.45953 58.8106 4.03316L50.7663 0.174427C50.2813 -0.0581424 49.7189 -0.0581424 49.2338 0.174427L41.19 4.03316C40.3015 4.45953 39.9244 5.53018 40.3472 6.42537C40.771 7.32101 41.8362 7.70198 42.7227 7.27445Z" fill="#D5D5D5"/>
|
||||
<path d="M67.9533 12.3945L78.6281 17.5147C78.875 17.6335 79.1361 17.6895 79.3932 17.6895C80.059 17.6895 80.6978 17.3115 81.0034 16.6656C81.426 15.7707 81.0494 14.6998 80.1606 14.2734L69.4856 9.15299C68.5982 8.7273 67.5345 9.10735 67.1105 10.0018C66.6875 10.8968 67.0645 11.9677 67.9533 12.3945Z" fill="#D5D5D5"/>
|
||||
<path d="M81.539 34.8098C82.4275 34.3836 82.8046 33.3128 82.3815 32.4176C81.9587 31.5231 80.8946 31.1423 80.0065 31.5694L73.167 34.8508L51.7477 24.577V16.5765C51.7477 15.5845 50.9503 14.7817 49.9659 14.7817C48.9817 14.7817 48.1841 15.5847 48.1841 16.5765V24.6095L26.8346 34.8499L20.6999 31.9073C19.8093 31.4809 18.7482 31.8612 18.3244 32.7563C17.9016 33.6513 18.2787 34.7224 19.1672 35.1488L25.8031 38.3318V61.6684L19.0593 64.903C18.1707 65.3294 17.7939 66.4 18.2165 67.2955C18.5221 67.9411 19.1606 68.3191 19.8266 68.3191C20.0837 68.3191 20.3447 68.2631 20.5917 68.1443L26.8349 65.1498L48.1841 75.3902V81.5074C48.1841 82.4992 48.9817 83.3022 49.9659 83.3022C50.9503 83.3022 51.7477 82.4989 51.7477 81.5074V75.4232L73.1657 65.15L79.6524 68.2615C79.9002 68.3801 80.1607 68.4363 80.4175 68.4363C81.0834 68.4363 81.7221 68.0583 82.0277 67.4124C82.4508 66.5175 82.0735 65.4466 81.1849 65.02L74.1977 61.6686V38.3318L81.539 34.8098ZM70.634 62.3879L51.7479 71.4466V49.0993L70.634 40.0401V62.3879ZM29.4788 61.8938C29.4472 61.8269 29.4053 61.7691 29.3668 61.708V40.0403L48.1841 49.0663V71.414L29.6409 62.5197C29.6239 62.3085 29.5745 62.0963 29.4788 61.8938ZM50.0003 27.715L69.0207 36.8382L50.0003 45.961L30.9799 36.8382L50.0003 27.715Z" fill="#D5D5D5"/>
|
||||
<path d="M78.6271 82.4859L67.9525 87.6061C67.0639 88.0327 66.6864 89.1036 67.1095 89.9979C67.4153 90.644 68.054 91.0215 68.7199 91.0215C68.9767 91.0215 69.2379 90.9655 69.485 90.8477L80.1598 85.7272C81.0483 85.3009 81.4252 84.2295 81.0025 83.3346C80.579 82.4401 79.5149 82.0616 78.6271 82.4859Z" fill="#D5D5D5"/>
|
||||
<path d="M57.2782 92.7267L51.748 95.3794V88.2271C51.748 87.2358 50.9506 86.4324 49.9662 86.4324C48.982 86.4324 48.1844 87.2358 48.1844 88.2271V95.3469L42.723 92.7267C41.8335 92.3024 40.7713 92.6808 40.3475 93.576C39.9246 94.4709 40.3015 95.5414 41.1903 95.9677L49.2346 99.826C49.4769 99.9418 49.7387 100 50.0008 100C50.2629 100 50.5248 99.9418 50.7671 99.826L58.8114 95.9677C59.6999 95.5414 60.077 94.4709 59.6541 93.576C59.2304 92.6808 58.166 92.3033 57.2782 92.7267Z" fill="#D5D5D5"/>
|
||||
<path d="M32.0476 87.6063L21.3728 82.4861C20.4863 82.0606 19.4217 82.4395 18.9975 83.3345C18.5749 84.2294 18.9517 85.3008 19.8403 85.7271L30.5153 90.8476C30.7622 90.9654 31.0233 91.0214 31.2802 91.0214C31.946 91.0214 32.5847 90.6439 32.8903 89.9978C33.3132 89.1037 32.9361 88.0329 32.0476 87.6063Z" fill="#D5D5D5"/>
|
||||
<path d="M11.5419 70.4973C11.1182 69.6028 10.0545 69.2239 9.16647 69.6487L3.56412 72.3354V65.6177C3.56412 64.6264 2.76668 63.823 1.78229 63.823C0.797668 63.823 0 64.6264 0 65.6177V74.5918C0 74.8162 0.0457694 75.0283 0.120686 75.2262C0.156892 75.8783 0.53193 76.465 1.12215 76.7485L9.16647 80.6072C9.41376 80.7254 9.67449 80.7818 9.93112 80.7818C10.5974 80.7818 11.2359 80.4038 11.5419 79.7581C11.9643 78.8632 11.5875 77.7923 10.699 77.3655L6.03295 75.1281L10.699 72.8902C11.5877 72.4636 11.9643 71.3923 11.5419 70.4973Z" fill="#D5D5D5"/>
|
||||
<path d="M1.78229 56.8224C2.76668 56.8224 3.56412 56.0192 3.56412 55.0273V44.4373C3.56412 43.446 2.76668 42.6426 1.78229 42.6426C0.797668 42.6426 0 43.446 0 44.4373V55.0273C0.00022771 56.0192 0.797896 56.8224 1.78229 56.8224Z" fill="#D5D5D5"/>
|
||||
<path d="M98.6173 23.1267L90.8342 19.3935C89.9443 18.9666 88.8825 19.3478 88.4589 20.2423C88.0363 21.1377 88.4132 22.2084 89.3017 22.635L93.9677 24.8729L89.3017 27.1107C88.4132 27.5371 88.0363 28.6077 88.4589 29.5029C88.7645 30.1488 89.4032 30.5268 90.0691 30.5268C90.3262 30.5268 90.5873 30.4708 90.8342 30.352L96.4365 27.6648V33.847C96.4365 34.8385 97.234 35.6417 98.2184 35.6417C99.2027 35.6417 100 34.8385 100 33.847V24.8731C100 24.0196 99.4088 23.3098 98.6173 23.1267Z" fill="#D5D5D5"/>
|
||||
<path d="M98.2184 42.6421C97.2337 42.6421 96.4365 43.4455 96.4365 44.4368V55.0268C96.4365 56.0187 97.234 56.8215 98.2184 56.8215C99.2027 56.8215 100 56.0185 100 55.0268V44.4368C100 43.4455 99.203 42.6421 98.2184 42.6421Z" fill="#D5D5D5"/>
|
||||
<path d="M98.2184 63.8228C97.2337 63.8228 96.4365 64.6262 96.4365 65.6175V72.3352L90.8342 69.6485C89.9443 69.223 88.8825 69.6021 88.4589 70.4971C88.0363 71.392 88.4132 72.4634 89.3017 72.8898L93.9677 75.1276L89.3017 77.365C88.4132 77.7918 88.0363 78.8627 88.4589 79.7577C88.7645 80.4033 89.4032 80.7813 90.0691 80.7813C90.3262 80.7813 90.5873 80.7249 90.8342 80.6068L98.8785 76.748C99.4687 76.4645 99.8438 75.8778 99.88 75.2258C99.9546 75.0278 100 74.8157 100 74.5914V65.6173C100 64.6262 99.203 63.8228 98.2184 63.8228Z" fill="#D5D5D5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.0 KiB |
@ -1,14 +0,0 @@
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Group 284">
|
||||
<g id="Group">
|
||||
<g id="Group_2">
|
||||
<path id="Vector" d="M37.8033 16.3571C37.2313 15.7851 36.3039 15.785 35.7318 16.3572L21.5532 30.5356L14.2681 23.2508C13.6962 22.6788 12.7686 22.6787 12.1966 23.2509C11.6246 23.8229 11.6246 24.7504 12.1966 25.3224L20.5174 33.643C20.8034 33.9291 21.1783 34.072 21.5531 34.072C21.928 34.072 22.3029 33.9291 22.5888 33.6429L37.8033 18.4287C38.3754 17.8567 38.3754 16.9292 37.8033 16.3571Z" fill="white"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group_3">
|
||||
<g id="Group_4">
|
||||
<path id="Vector_2" d="M42.6776 7.32236C37.9558 2.60049 31.6776 0 25 0C18.3223 0 12.0442 2.60049 7.32236 7.32236C2.60039 12.0443 0 18.3224 0 25C0 31.6778 2.60039 37.9559 7.32236 42.6777C12.0441 47.3996 18.3223 50 25 50C31.6777 50 37.9558 47.3996 42.6776 42.6777C47.3995 37.9559 50 31.6778 50 25C50 18.3224 47.3995 12.0443 42.6776 7.32236ZM25 47.0703C12.8304 47.0703 2.92969 37.1696 2.92969 25C2.92969 12.8304 12.8304 2.92969 25 2.92969C37.1696 2.92969 47.0703 12.8304 47.0703 25C47.0703 37.1696 37.1696 47.0703 25 47.0703Z" fill="white"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@ -241,16 +241,14 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> reSendOtp() async {
|
||||
reSendOtp() async {
|
||||
try {
|
||||
emit(AuthLoading());
|
||||
await AuthenticationAPI.sendOtp(
|
||||
body: {'email': email, 'type': 'VERIFICATION'});
|
||||
emit(ResendOtpSuccess());
|
||||
return true;
|
||||
} catch (_) {
|
||||
emit(AuthLoginError(message: 'Something went wrong'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import 'package:pin_code_fields/pin_code_fields.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/auth/view/create_new_password.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/success_dialog.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
@ -41,19 +40,13 @@ class _OtpViewState extends State<OtpView> {
|
||||
_lifecycleEventHandler = LifecycleEventHandler(
|
||||
resumeCallBack: () async {
|
||||
SharedPreferencesHelper.saveBoolToSP('timeStampSaved', false);
|
||||
String timeStampInBackground =
|
||||
await SharedPreferencesHelper.readStringFromSP('timeStamp');
|
||||
int savedCounter =
|
||||
await SharedPreferencesHelper.readIntFromSP('savedCounter');
|
||||
String timeStampInBackground = await SharedPreferencesHelper.readStringFromSP('timeStamp');
|
||||
int savedCounter = await SharedPreferencesHelper.readIntFromSP('savedCounter');
|
||||
DateTime currentTime = DateTime.now();
|
||||
int differenceInSeconds = timeStampInBackground.isNotEmpty
|
||||
? currentTime
|
||||
.difference(DateTime.parse(timeStampInBackground))
|
||||
.inSeconds
|
||||
? currentTime.difference(DateTime.parse(timeStampInBackground)).inSeconds
|
||||
: 0;
|
||||
remainingSec = differenceInSeconds > savedCounter
|
||||
? 0
|
||||
: savedCounter - differenceInSeconds;
|
||||
remainingSec = differenceInSeconds > savedCounter ? 0 : savedCounter - differenceInSeconds;
|
||||
timerStarted = true;
|
||||
startTimer(remainingSec ?? 0);
|
||||
return;
|
||||
@ -82,8 +75,7 @@ class _OtpViewState extends State<OtpView> {
|
||||
}
|
||||
|
||||
handleTimerOnBackground() async {
|
||||
bool timeStampSaved =
|
||||
await SharedPreferencesHelper.readBoolFromSP('timeStampSaved') ?? false;
|
||||
bool timeStampSaved = await SharedPreferencesHelper.readBoolFromSP('timeStampSaved') ?? false;
|
||||
if (!timeStampSaved) {
|
||||
final dateInString = DateTime.now().toString();
|
||||
SharedPreferencesHelper.saveIntToSP('savedCounter', remainingSec ?? 0);
|
||||
@ -123,8 +115,7 @@ class _OtpViewState extends State<OtpView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String maskedEmail =
|
||||
AuthCubit.get(context).maskEmail(AuthCubit.get(context).email);
|
||||
String maskedEmail = AuthCubit.get(context).maskEmail(AuthCubit.get(context).email);
|
||||
return BlocConsumer<AuthCubit, AuthState>(
|
||||
listener: (context, state) {
|
||||
if (state is AuthOtpSuccess) {
|
||||
@ -208,10 +199,7 @@ class _OtpViewState extends State<OtpView> {
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: 'We have sent the verification code to',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.copyWith(
|
||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||
color: Colors.white,
|
||||
fontWeight: FontsManager.regular,
|
||||
fontSize: 14,
|
||||
@ -219,10 +207,7 @@ class _OtpViewState extends State<OtpView> {
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' $maskedEmail',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.copyWith(
|
||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontsManager.bold,
|
||||
fontSize: 14,
|
||||
@ -230,10 +215,7 @@ class _OtpViewState extends State<OtpView> {
|
||||
),
|
||||
TextSpan(
|
||||
text: ' change email?',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.copyWith(
|
||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||
color: const Color(0xFF87C7FF),
|
||||
fontWeight: FontsManager.regular,
|
||||
fontSize: 14,
|
||||
@ -257,8 +239,7 @@ class _OtpViewState extends State<OtpView> {
|
||||
keyboardType: TextInputType.number,
|
||||
autoFocus: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
animationDuration:
|
||||
const Duration(milliseconds: 30),
|
||||
animationDuration: const Duration(milliseconds: 30),
|
||||
beforeTextPaste: (text) {
|
||||
// Allow pasting only if all characters are numeric
|
||||
return int.tryParse(text!) != null;
|
||||
@ -281,27 +262,18 @@ class _OtpViewState extends State<OtpView> {
|
||||
errorBorderWidth: 1,
|
||||
borderWidth: 1,
|
||||
errorBorderColor: Colors.red,
|
||||
activeColor: state is AuthLoginError
|
||||
? Colors.red
|
||||
: Colors.white,
|
||||
inactiveColor: state is AuthLoginError
|
||||
? Colors.red
|
||||
: Colors.white,
|
||||
activeFillColor: state is AuthLoginError
|
||||
? Colors.red
|
||||
: Colors.white,
|
||||
inactiveFillColor: state is AuthLoginError
|
||||
? Colors.red
|
||||
: Colors.white,
|
||||
selectedFillColor: state is AuthLoginError
|
||||
? Colors.red
|
||||
: Colors.white,
|
||||
activeColor: state is AuthLoginError ? Colors.red : Colors.white,
|
||||
inactiveColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
activeFillColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
inactiveFillColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
selectedFillColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
disabledColor: Colors.white,
|
||||
fieldHeight: 56,
|
||||
fieldWidth:
|
||||
MediaQuery.sizeOf(context).width > 340
|
||||
? 40
|
||||
: 20,
|
||||
fieldWidth: MediaQuery.sizeOf(context).width > 340 ? 40 : 20,
|
||||
// fieldWidth: 40,
|
||||
selectedColor: Colors.white,
|
||||
shape: PinCodeFieldShape.box,
|
||||
@ -323,12 +295,10 @@ class _OtpViewState extends State<OtpView> {
|
||||
isDone: state is AuthLoginSuccess,
|
||||
isLoading: state is AuthLoading,
|
||||
customButtonStyle: ButtonStyle(
|
||||
backgroundColor:
|
||||
MaterialStateProperty.all(
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
Colors.black.withOpacity(.25),
|
||||
),
|
||||
foregroundColor:
|
||||
MaterialStateProperty.all(
|
||||
foregroundColor: MaterialStateProperty.all(
|
||||
Colors.white,
|
||||
),
|
||||
),
|
||||
@ -337,8 +307,7 @@ class _OtpViewState extends State<OtpView> {
|
||||
),
|
||||
onPressed: () {
|
||||
if ((state is! AuthLoading)) {
|
||||
AuthCubit.get(context)
|
||||
.verifyOtp(widget.isForgetPage);
|
||||
AuthCubit.get(context).verifyOtp(widget.isForgetPage);
|
||||
FocusScope.of(context).unfocus();
|
||||
}
|
||||
},
|
||||
@ -352,12 +321,10 @@ class _OtpViewState extends State<OtpView> {
|
||||
isDone: state is AuthLoginSuccess,
|
||||
isLoading: state is AuthLoading,
|
||||
customButtonStyle: ButtonStyle(
|
||||
backgroundColor:
|
||||
MaterialStateProperty.all(
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
Colors.black.withOpacity(.25),
|
||||
),
|
||||
foregroundColor:
|
||||
MaterialStateProperty.all(
|
||||
foregroundColor: MaterialStateProperty.all(
|
||||
Colors.white,
|
||||
),
|
||||
),
|
||||
@ -374,20 +341,8 @@ class _OtpViewState extends State<OtpView> {
|
||||
return;
|
||||
}
|
||||
if ((state is! AuthLoading)) {
|
||||
bool success = await AuthCubit.get(context)
|
||||
.reSendOtp();
|
||||
await AuthCubit.get(context).reSendOtp();
|
||||
FocusScope.of(context).unfocus();
|
||||
if(success){
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => SuccessDialog(
|
||||
key: ValueKey('SuccessDialog'),
|
||||
message: 'New OTP sent!',));
|
||||
}
|
||||
Future.delayed(Duration(seconds: 2),
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@ -1,326 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/one_gang_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
import 'one_gang_event.dart';
|
||||
|
||||
class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
||||
final String oneGangId;
|
||||
final String switchCode;
|
||||
OneGangModel deviceStatus = OneGangModel(
|
||||
firstSwitch: false,
|
||||
firstCountDown: 0,
|
||||
);
|
||||
Timer? _timer;
|
||||
|
||||
bool oneGangGroup = false;
|
||||
List<DeviceModel> devicesList = [];
|
||||
|
||||
OneGangBloc({required this.oneGangId,required this.switchCode}) : super(InitialState()) {
|
||||
on<InitialEvent>(_fetchOneGangStatus);
|
||||
on<OneGangUpdated>(_oneGangUpdated);
|
||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||
on<ChangeSlidingSegment>(_changeSliding);
|
||||
on<SetCounterValue>(_setCounterValue);
|
||||
on<GetCounterEvent>(_getCounterValue);
|
||||
on<TickTimer>(_onTickTimer);
|
||||
on<OnClose>(_onClose);
|
||||
|
||||
|
||||
|
||||
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
on<ThreeGangSave>(saveSchedule);
|
||||
on<GetScheduleEvent>(getSchedule);
|
||||
on<ToggleScheduleEvent>(toggleChange);
|
||||
on<DeleteScheduleEvent>(deleteSchedule);
|
||||
}
|
||||
|
||||
void _fetchOneGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
try {
|
||||
var response = await DevicesAPI.getDeviceStatus(oneGangId);
|
||||
List<StatusModel> statusModelList = [];
|
||||
for (var status in response['status']) {
|
||||
statusModelList.add(StatusModel.fromJson(status));
|
||||
}
|
||||
deviceStatus = OneGangModel.fromJson(statusModelList);
|
||||
emit(UpdateState(oneGangModel: deviceStatus));
|
||||
_listenToChanges();
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_listenToChanges() {
|
||||
try {
|
||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneGangId');
|
||||
Stream<DatabaseEvent> stream = ref.onValue;
|
||||
|
||||
stream.listen((DatabaseEvent event) async {
|
||||
if (_timer != null) {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
}
|
||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
||||
List<StatusModel> statusList = [];
|
||||
|
||||
usersMap['status'].forEach((element) {
|
||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
||||
});
|
||||
|
||||
deviceStatus = OneGangModel.fromJson(statusList);
|
||||
if (!isClosed) {
|
||||
add(OneGangUpdated());
|
||||
}
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
_oneGangUpdated(OneGangUpdated event, Emitter<OneGangState> emit) {
|
||||
emit(UpdateState(oneGangModel: deviceStatus));
|
||||
}
|
||||
|
||||
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<OneGangState> emit) async {
|
||||
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||
try {
|
||||
deviceStatus.firstSwitch = !event.value;
|
||||
emit(UpdateState(oneGangModel: deviceStatus));
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: oneGangGroup ? event.deviceId : oneGangId,
|
||||
code: 'switch_1',
|
||||
value: !event.value),
|
||||
oneGangGroup ? event.deviceId : oneGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: oneGangGroup));
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
add(InitialEvent(groupScreen: oneGangGroup));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _changeSliding(ChangeSlidingSegment event, Emitter<OneGangState> emit) async {
|
||||
emit(ChangeSlidingSegmentState(value: event.value));
|
||||
}
|
||||
|
||||
void _setCounterValue(SetCounterValue event, Emitter<OneGangState> emit) async {
|
||||
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||
int seconds = 0;
|
||||
try {
|
||||
seconds = event.duration.inSeconds;
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(deviceId: oneGangId, code: event.deviceCode, value: seconds),
|
||||
oneGangId);
|
||||
|
||||
if (response['success'] ?? false) {
|
||||
if (event.deviceCode == 'countdown_1') {
|
||||
deviceStatus.firstCountDown = seconds;
|
||||
}
|
||||
} else {
|
||||
emit(const FailedState(error: 'Something went wrong'));
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
if (seconds > 0) {
|
||||
_onStartTimer(seconds);
|
||||
} else {
|
||||
_timer?.cancel();
|
||||
emit(TimerRunComplete());
|
||||
}
|
||||
}
|
||||
|
||||
void _getCounterValue(GetCounterEvent event, Emitter<OneGangState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
try {
|
||||
var response = await DevicesAPI.getDeviceStatus(oneGangId);
|
||||
List<StatusModel> statusModelList = [];
|
||||
for (var status in response['status']) {
|
||||
statusModelList.add(StatusModel.fromJson(status));
|
||||
}
|
||||
deviceStatus = OneGangModel.fromJson(statusModelList);
|
||||
|
||||
if (event.deviceCode == 'countdown_1') {
|
||||
deviceStatus.firstCountDown > 0
|
||||
? _onStartTimer(deviceStatus.firstCountDown)
|
||||
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void _onClose(OnClose event, Emitter<OneGangState> emit) {
|
||||
_timer?.cancel();
|
||||
}
|
||||
|
||||
void _onStartTimer(int seconds) {
|
||||
_timer?.cancel();
|
||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
add(TickTimer(seconds - timer.tick));
|
||||
});
|
||||
}
|
||||
|
||||
void _onTickTimer(TickTimer event, Emitter<OneGangState> emit) {
|
||||
if (event.remainingTime > 0) {
|
||||
emit(TimerRunInProgress(event.remainingTime));
|
||||
} else {
|
||||
_timer?.cancel();
|
||||
emit(TimerRunComplete());
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, String>> days = [
|
||||
{"day": "Sun", "key": "Sun"},
|
||||
{"day": "Mon", "key": "Mon"},
|
||||
{"day": "Tue", "key": "Tue"},
|
||||
{"day": "Wed", "key": "Wed"},
|
||||
{"day": "Thu", "key": "Thu"},
|
||||
{"day": "Fri", "key": "Fri"},
|
||||
{"day": "Sat", "key": "Sat"},
|
||||
];
|
||||
|
||||
Future<void> saveSchedule(ThreeGangSave event, Emitter<OneGangState> emit,) async {
|
||||
try {
|
||||
if(selectedDays.isNotEmpty) {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.postSchedule(
|
||||
category: switchCode,
|
||||
deviceId: oneGangId,
|
||||
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||
code: switchCode,
|
||||
value: toggleSchedule,
|
||||
days: selectedDays);
|
||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||
add(GetScheduleEvent());
|
||||
emit(ThreeGangSaveSchedule());
|
||||
toggleCreateSchedule();
|
||||
}else{
|
||||
CustomSnackBar.displaySnackBar('Please select days');
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> getSchedule(GetScheduleEvent event, Emitter<OneGangState> emit,) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.getSchedule(
|
||||
category: switchCode,
|
||||
deviceId: oneGangId ,
|
||||
);
|
||||
List<dynamic> jsonData = response;
|
||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||
emit(InitialState());
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||
if (dateTime == null) return null;
|
||||
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||
dateTime.day, dateTime.hour, dateTime.minute);
|
||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||
}
|
||||
|
||||
Future toggleChange(
|
||||
ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.changeSchedule(
|
||||
scheduleId: event.id, deviceUuid: oneGangId, enable: event.toggle);
|
||||
if (response == true) {
|
||||
add(GetScheduleEvent());
|
||||
toggleSchedule = event.toggle;
|
||||
return toggleSchedule;
|
||||
}
|
||||
emit(IsToggleState(onOff: toggleSchedule));
|
||||
add(const ChangeSlidingSegment(value: 1));
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future deleteSchedule(
|
||||
DeleteScheduleEvent event, Emitter<OneGangState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.deleteSchedule(
|
||||
scheduleId: event.id,
|
||||
deviceUuid: oneGangId, );
|
||||
if (response == true) {
|
||||
add(GetScheduleEvent());
|
||||
return toggleSchedule;
|
||||
}
|
||||
emit(IsToggleState(onOff: toggleSchedule));
|
||||
add(const ChangeSlidingSegment(value: 1));
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void toggleCreateSchedule() {
|
||||
emit(LoadingInitialState());
|
||||
createSchedule = !createSchedule;
|
||||
selectedDays.clear();
|
||||
selectedTime=DateTime.now();
|
||||
emit(UpdateCreateScheduleState(createSchedule));
|
||||
emit(ChangeSlidingSegmentState(value: 1));
|
||||
}
|
||||
|
||||
bool toggleSchedule = true;
|
||||
List<String> selectedDays = [];
|
||||
bool createSchedule = false;
|
||||
List<ScheduleModel> listSchedule = [];
|
||||
DateTime? selectedTime=DateTime.now();
|
||||
Future<void> toggleDaySelection(
|
||||
ToggleDaySelectionEvent event,
|
||||
Emitter<OneGangState> emit,
|
||||
) async {
|
||||
emit(LoadingInitialState());
|
||||
if (selectedDays.contains(event.key)) {
|
||||
selectedDays.remove(event.key);
|
||||
} else {
|
||||
selectedDays.add(event.key);
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
add(ChangeSlidingSegment(value: 1));
|
||||
}
|
||||
|
||||
int selectedTabIndex = 0;
|
||||
|
||||
void toggleSelectedIndex(index) {
|
||||
emit(LoadingInitialState());
|
||||
selectedTabIndex = index;
|
||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,116 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class OneGangEvent extends Equatable {
|
||||
const OneGangEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class LoadingEvent extends OneGangEvent {}
|
||||
|
||||
class OneGangUpdated extends OneGangEvent {}
|
||||
|
||||
class InitialEvent extends OneGangEvent {
|
||||
final bool groupScreen;
|
||||
const InitialEvent({required this.groupScreen});
|
||||
@override
|
||||
List<Object> get props => [groupScreen];
|
||||
}
|
||||
|
||||
class ChangeFirstSwitchStatusEvent extends OneGangEvent {
|
||||
final bool value;
|
||||
final String deviceId;
|
||||
const ChangeFirstSwitchStatusEvent({required this.value, this.deviceId = ''});
|
||||
@override
|
||||
List<Object> get props => [value, deviceId];
|
||||
}
|
||||
|
||||
class ChangeSecondSwitchStatusEvent extends OneGangEvent {
|
||||
final bool value;
|
||||
final String deviceId;
|
||||
const ChangeSecondSwitchStatusEvent({required this.value, this.deviceId = ''});
|
||||
@override
|
||||
List<Object> get props => [value, deviceId];
|
||||
}
|
||||
|
||||
|
||||
class AllOffEvent extends OneGangEvent {}
|
||||
|
||||
class AllOnEvent extends OneGangEvent {}
|
||||
|
||||
class GroupAllOnEvent extends OneGangEvent {}
|
||||
|
||||
class GroupAllOffEvent extends OneGangEvent {}
|
||||
|
||||
class ChangeSlidingSegment extends OneGangEvent {
|
||||
final int value;
|
||||
const ChangeSlidingSegment({required this.value});
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
}
|
||||
|
||||
class GetCounterEvent extends OneGangEvent {
|
||||
final String deviceCode;
|
||||
const GetCounterEvent({required this.deviceCode});
|
||||
@override
|
||||
List<Object> get props => [deviceCode];
|
||||
}
|
||||
|
||||
class SetCounterValue extends OneGangEvent {
|
||||
final Duration duration;
|
||||
final String deviceCode;
|
||||
const SetCounterValue({required this.duration, required this.deviceCode});
|
||||
@override
|
||||
List<Object> get props => [duration, deviceCode];
|
||||
}
|
||||
|
||||
class StartTimer extends OneGangEvent {
|
||||
final int duration;
|
||||
|
||||
const StartTimer(this.duration);
|
||||
|
||||
@override
|
||||
List<Object> get props => [duration];
|
||||
}
|
||||
|
||||
class TickTimer extends OneGangEvent {
|
||||
final int remainingTime;
|
||||
|
||||
const TickTimer(this.remainingTime);
|
||||
|
||||
@override
|
||||
List<Object> get props => [remainingTime];
|
||||
}
|
||||
|
||||
class StopTimer extends OneGangEvent {}
|
||||
|
||||
class OnClose extends OneGangEvent {}
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------- Schedule ----------=---------
|
||||
class GetScheduleEvent extends OneGangEvent {}
|
||||
class ThreeGangSave extends OneGangEvent {}
|
||||
class ToggleScheduleEvent extends OneGangEvent {
|
||||
final String id;
|
||||
final bool toggle;
|
||||
const ToggleScheduleEvent({required this.toggle,required this.id});
|
||||
@override
|
||||
List<Object> get props => [toggle,id];
|
||||
}
|
||||
class ToggleDaySelectionEvent extends OneGangEvent {
|
||||
|
||||
final String key;
|
||||
|
||||
const ToggleDaySelectionEvent({required this.key});
|
||||
@override
|
||||
List<Object> get props => [key];
|
||||
}
|
||||
class DeleteScheduleEvent extends OneGangEvent {
|
||||
final String id;
|
||||
const DeleteScheduleEvent({required this.id});
|
||||
@override
|
||||
List<Object> get props => [id];
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.dart';
|
||||
import 'package:syncrow_app/features/devices/model/one_gang_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
|
||||
|
||||
|
||||
class OneGangState extends Equatable {
|
||||
const OneGangState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class InitialState extends OneGangState {}
|
||||
|
||||
class LoadingInitialState extends OneGangState {}
|
||||
|
||||
class UpdateState extends OneGangState {
|
||||
final OneGangModel oneGangModel;
|
||||
const UpdateState({required this.oneGangModel});
|
||||
|
||||
@override
|
||||
List<Object> get props => [TwoGangModel];
|
||||
}
|
||||
|
||||
class LoadingNewSate extends OneGangState {
|
||||
final OneGangModel oneGangModel;
|
||||
const LoadingNewSate({required this.oneGangModel});
|
||||
|
||||
@override
|
||||
List<Object> get props => [OneGangModel];
|
||||
}
|
||||
|
||||
class UpdateGroupState extends OneGangState {
|
||||
final List<GroupTwoGangModel> twoGangList;
|
||||
final bool allSwitches;
|
||||
|
||||
const UpdateGroupState({required this.twoGangList, required this.allSwitches});
|
||||
|
||||
@override
|
||||
List<Object> get props => [twoGangList, allSwitches];
|
||||
}
|
||||
|
||||
class FailedState extends OneGangState {
|
||||
final String error;
|
||||
|
||||
const FailedState({required this.error});
|
||||
|
||||
@override
|
||||
List<Object> get props => [error];
|
||||
}
|
||||
|
||||
class ChangeSlidingSegmentState extends OneGangState {
|
||||
final int value;
|
||||
|
||||
const ChangeSlidingSegmentState({required this.value});
|
||||
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
}
|
||||
|
||||
class UpdateTimerState extends OneGangState {
|
||||
final int seconds;
|
||||
const UpdateTimerState({required this.seconds});
|
||||
|
||||
@override
|
||||
List<Object> get props => [seconds];
|
||||
}
|
||||
|
||||
class TimerRunInProgress extends OneGangState {
|
||||
final int remainingTime;
|
||||
|
||||
const TimerRunInProgress(this.remainingTime);
|
||||
|
||||
@override
|
||||
List<Object> get props => [remainingTime];
|
||||
}
|
||||
|
||||
class TimerRunComplete extends OneGangState {}
|
||||
class ThreeGangSaveSchedule extends OneGangState {}
|
||||
class IsToggleState extends OneGangState {
|
||||
final bool? onOff;
|
||||
const IsToggleState({this.onOff});
|
||||
}
|
||||
class ChangeTimeState extends OneGangState {}
|
||||
class UpdateCreateScheduleState extends OneGangState {
|
||||
final bool createSchedule;
|
||||
UpdateCreateScheduleState(this.createSchedule);
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
@ -8,16 +7,12 @@ import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_sta
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
|
||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
|
||||
|
||||
class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
final String threeGangId;
|
||||
final String switchCode;
|
||||
ThreeGangModel deviceStatus = ThreeGangModel(
|
||||
firstSwitch: false,
|
||||
secondSwitch: false,
|
||||
@ -35,7 +30,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
List<GroupThreeGangModel> groupThreeGangList = [];
|
||||
bool allSwitchesOn = true;
|
||||
|
||||
ThreeGangBloc({required this.threeGangId,required this.switchCode}) : super(InitialState()) {
|
||||
ThreeGangBloc({required this.threeGangId}) : super(InitialState()) {
|
||||
on<InitialEvent>(_fetchThreeGangStatus);
|
||||
on<ThreeGangUpdated>(_threeGangUpdated);
|
||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||
@ -50,14 +45,6 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
on<OnClose>(_onClose);
|
||||
on<GroupAllOnEvent>(_groupAllOn);
|
||||
on<GroupAllOffEvent>(_groupAllOff);
|
||||
|
||||
|
||||
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
on<ThreeGangSave>(saveSchedule);
|
||||
on<GetScheduleEvent>(getSchedule);
|
||||
on<ToggleScheduleEvent>(toggleChange);
|
||||
on<DeleteScheduleEvent>(deleteSchedule);
|
||||
}
|
||||
|
||||
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
|
||||
@ -203,6 +190,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
@ -472,6 +460,9 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
|
||||
void _onClose(OnClose event, Emitter<ThreeGangState> emit) {
|
||||
_timer?.cancel();
|
||||
// _firstSwitchTimer?.cancel();
|
||||
// _secondSwitchTimer?.cancel();
|
||||
// _thirdSwitchTimer?.cancel();
|
||||
}
|
||||
|
||||
void _onStartTimer(int seconds) {
|
||||
@ -489,143 +480,4 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||
emit(TimerRunComplete());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
List<Map<String, String>> days = [
|
||||
{"day": "Sun", "key": "Sun"},
|
||||
{"day": "Mon", "key": "Mon"},
|
||||
{"day": "Tue", "key": "Tue"},
|
||||
{"day": "Wed", "key": "Wed"},
|
||||
{"day": "Thu", "key": "Thu"},
|
||||
{"day": "Fri", "key": "Fri"},
|
||||
{"day": "Sat", "key": "Sat"},
|
||||
];
|
||||
|
||||
Future<void> toggleDaySelection(
|
||||
ToggleDaySelectionEvent event,
|
||||
Emitter<ThreeGangState> emit,
|
||||
) async {
|
||||
emit(LoadingInitialState());
|
||||
if (selectedDays.contains(event.key)) {
|
||||
selectedDays.remove(event.key);
|
||||
} else {
|
||||
selectedDays.add(event.key);
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
add(ChangeSlidingSegment(value: 1));
|
||||
}
|
||||
|
||||
Future<void> saveSchedule(ThreeGangSave event, Emitter<ThreeGangState> emit,) async {
|
||||
try {
|
||||
if(selectedDays.isNotEmpty) {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.postSchedule(
|
||||
category: switchCode,
|
||||
deviceId: threeGangId,
|
||||
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||
code: switchCode,
|
||||
value: toggleSchedule,
|
||||
days: selectedDays);
|
||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||
add(GetScheduleEvent());
|
||||
emit(ThreeGangSaveSchedule());
|
||||
toggleCreateSchedule();
|
||||
}else{
|
||||
CustomSnackBar.displaySnackBar('Please select days');
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> getSchedule(GetScheduleEvent event, Emitter<ThreeGangState> emit,) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.getSchedule(
|
||||
category: switchCode,
|
||||
deviceId: threeGangId ,
|
||||
);
|
||||
List<dynamic> jsonData = response;
|
||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||
emit(InitialState());
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||
if (dateTime == null) return null;
|
||||
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||
dateTime.day, dateTime.hour, dateTime.minute);
|
||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||
}
|
||||
|
||||
Future toggleChange(
|
||||
ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.changeSchedule(
|
||||
scheduleId: event.id, deviceUuid: threeGangId, enable: event.toggle);
|
||||
if (response == true) {
|
||||
add(GetScheduleEvent());
|
||||
toggleSchedule = event.toggle;
|
||||
return toggleSchedule;
|
||||
}
|
||||
emit(IsToggleState(onOff: toggleSchedule));
|
||||
add(const ChangeSlidingSegment(value: 1));
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future deleteSchedule(
|
||||
DeleteScheduleEvent event, Emitter<ThreeGangState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.deleteSchedule(
|
||||
scheduleId: event.id,
|
||||
deviceUuid: threeGangId, );
|
||||
if (response == true) {
|
||||
add(GetScheduleEvent());
|
||||
return toggleSchedule;
|
||||
}
|
||||
emit(IsToggleState(onOff: toggleSchedule));
|
||||
add(const ChangeSlidingSegment(value: 1));
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void toggleCreateSchedule() {
|
||||
emit(LoadingInitialState());
|
||||
createSchedule = !createSchedule;
|
||||
selectedDays.clear();
|
||||
selectedTime=DateTime.now();
|
||||
emit(UpdateCreateScheduleState(createSchedule));
|
||||
emit(ChangeSlidingSegmentState(value: 1));
|
||||
}
|
||||
|
||||
int selectedTabIndex = 0;
|
||||
|
||||
void toggleSelectedIndex(index) {
|
||||
emit(LoadingInitialState());
|
||||
selectedTabIndex = index;
|
||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||
}
|
||||
|
||||
bool toggleSchedule = true;
|
||||
List<String> selectedDays = [];
|
||||
bool createSchedule = false;
|
||||
List<ScheduleModel> listSchedule = [];
|
||||
DateTime? selectedTime=DateTime.now();
|
||||
|
||||
}
|
||||
|
||||
@ -93,29 +93,3 @@ class TickTimer extends ThreeGangEvent {
|
||||
class StopTimer extends ThreeGangEvent {}
|
||||
|
||||
class OnClose extends ThreeGangEvent {}
|
||||
|
||||
|
||||
//------------------- Schedule ----------=---------
|
||||
class GetScheduleEvent extends ThreeGangEvent {}
|
||||
class ThreeGangSave extends ThreeGangEvent {}
|
||||
class ToggleScheduleEvent extends ThreeGangEvent {
|
||||
final String id;
|
||||
final bool toggle;
|
||||
const ToggleScheduleEvent({required this.toggle,required this.id});
|
||||
@override
|
||||
List<Object> get props => [toggle,id];
|
||||
}
|
||||
class ToggleDaySelectionEvent extends ThreeGangEvent {
|
||||
|
||||
final String key;
|
||||
|
||||
const ToggleDaySelectionEvent({required this.key});
|
||||
@override
|
||||
List<Object> get props => [key];
|
||||
}
|
||||
class DeleteScheduleEvent extends ThreeGangEvent {
|
||||
final String id;
|
||||
const DeleteScheduleEvent({required this.id});
|
||||
@override
|
||||
List<Object> get props => [id];
|
||||
}
|
||||
|
||||
@ -75,15 +75,3 @@ class TimerRunInProgress extends ThreeGangState {
|
||||
}
|
||||
|
||||
class TimerRunComplete extends ThreeGangState {}
|
||||
|
||||
|
||||
class ThreeGangSaveSchedule extends ThreeGangState {}
|
||||
class IsToggleState extends ThreeGangState {
|
||||
final bool? onOff;
|
||||
const IsToggleState({this.onOff});
|
||||
}
|
||||
class ChangeTimeState extends ThreeGangState {}
|
||||
class UpdateCreateScheduleState extends ThreeGangState {
|
||||
final bool createSchedule;
|
||||
UpdateCreateScheduleState(this.createSchedule);
|
||||
}
|
||||
|
||||
@ -1,553 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.dart';
|
||||
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
|
||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
|
||||
class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
||||
final String twoGangId;
|
||||
final String switchCode;
|
||||
TwoGangModel deviceStatus = TwoGangModel(
|
||||
firstSwitch: false,
|
||||
secondSwitch: false,
|
||||
firstCountDown: 0,
|
||||
secondCountDown: 0,
|
||||
);
|
||||
Timer? _timer;
|
||||
|
||||
bool twoGangGroup = false;
|
||||
List<DeviceModel> devicesList = [];
|
||||
List<GroupTwoGangModel> groupTwoGangList = [];
|
||||
bool allSwitchesOn = true;
|
||||
bool toggleSchedule = true;
|
||||
List<String> selectedDays = [];
|
||||
|
||||
bool createSchedule = false;
|
||||
List<ScheduleModel> listSchedule = [];
|
||||
|
||||
TwoGangBloc({required this.twoGangId,required this.switchCode}) : super(InitialState()) {
|
||||
on<InitialEvent>(_fetchTwoGangStatus);
|
||||
on<TwoGangUpdated>(_twoGangUpdated);
|
||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||
on<ChangeSecondSwitchStatusEvent>(_changeSecondSwitch);
|
||||
on<AllOffEvent>(_allOff);
|
||||
on<AllOnEvent>(_allOn);
|
||||
on<ChangeSlidingSegment>(_changeSliding);
|
||||
on<SetCounterValue>(_setCounterValue);
|
||||
on<GetCounterEvent>(_getCounterValue);
|
||||
on<TickTimer>(_onTickTimer);
|
||||
on<OnClose>(_onClose);
|
||||
on<GroupAllOnEvent>(_groupAllOn);
|
||||
on<GroupAllOffEvent>(_groupAllOff);
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
on<TwoGangSave>(saveSchedule);
|
||||
on<GetScheduleEvent>(getSchedule);
|
||||
on<ToggleScheduleEvent>(toggleRepeat);
|
||||
on<DeleteScheduleEvent>(deleteSchedule);
|
||||
|
||||
}
|
||||
|
||||
DateTime? selectedTime = DateTime.now();
|
||||
|
||||
void toggleCreateSchedule() {
|
||||
emit(LoadingInitialState());
|
||||
createSchedule = !createSchedule;
|
||||
selectedDays.clear();
|
||||
selectedTime=DateTime.now();
|
||||
emit(UpdateCreateScheduleState(createSchedule));
|
||||
emit(ChangeSlidingSegmentState(value: 1));
|
||||
}
|
||||
int selectedTabIndex = 0;
|
||||
|
||||
void toggleSelectedIndex(index) {
|
||||
emit(LoadingInitialState());
|
||||
selectedTabIndex = index;
|
||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||
}
|
||||
|
||||
void _fetchTwoGangStatus(InitialEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
try {
|
||||
twoGangGroup = event.groupScreen;
|
||||
if (twoGangGroup) {
|
||||
devicesList = [];
|
||||
groupTwoGangList = [];
|
||||
allSwitchesOn = true;
|
||||
devicesList = await DevicesAPI.getDeviceByGroupName(
|
||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
|
||||
|
||||
for (int i = 0; i < devicesList.length; i++) {
|
||||
var response =
|
||||
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||
List<StatusModel> statusModelList = [];
|
||||
for (var status in response['status']) {
|
||||
statusModelList.add(StatusModel.fromJson(status));
|
||||
}
|
||||
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
||||
|
||||
groupTwoGangList.add(GroupTwoGangModel(
|
||||
deviceId: devicesList[i].uuid ?? '',
|
||||
deviceName: devicesList[i].name ?? '',
|
||||
firstSwitch: deviceStatus.firstSwitch,
|
||||
secondSwitch: deviceStatus.secondSwitch,
|
||||
));
|
||||
}
|
||||
|
||||
if (groupTwoGangList.isNotEmpty) {
|
||||
groupTwoGangList.firstWhere((element) {
|
||||
if (!element.firstSwitch || !element.secondSwitch) {
|
||||
allSwitchesOn = false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
emit(UpdateGroupState(
|
||||
twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
|
||||
} else {
|
||||
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
||||
List<StatusModel> statusModelList = [];
|
||||
for (var status in response['status']) {
|
||||
statusModelList.add(StatusModel.fromJson(status));
|
||||
}
|
||||
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
||||
emit(UpdateState(twoGangModel: deviceStatus));
|
||||
_listenToChanges();
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_listenToChanges() {
|
||||
try {
|
||||
DatabaseReference ref =
|
||||
FirebaseDatabase.instance.ref('device-status/$twoGangId');
|
||||
Stream<DatabaseEvent> stream = ref.onValue;
|
||||
|
||||
stream.listen((DatabaseEvent event) async {
|
||||
if (_timer != null) {
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
}
|
||||
Map<dynamic, dynamic> usersMap =
|
||||
event.snapshot.value as Map<dynamic, dynamic>;
|
||||
List<StatusModel> statusList = [];
|
||||
|
||||
usersMap['status'].forEach((element) {
|
||||
statusList
|
||||
.add(StatusModel(code: element['code'], value: element['value']));
|
||||
});
|
||||
|
||||
deviceStatus = TwoGangModel.fromJson(statusList);
|
||||
if (!isClosed) {
|
||||
add(TwoGangUpdated());
|
||||
}
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
_twoGangUpdated(TwoGangUpdated event, Emitter<TwoGangState> emit) {
|
||||
emit(UpdateState(twoGangModel: deviceStatus));
|
||||
}
|
||||
|
||||
void _changeFirstSwitch(
|
||||
ChangeFirstSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||
try {
|
||||
deviceStatus.firstSwitch = !event.value;
|
||||
emit(UpdateState(twoGangModel: deviceStatus));
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: twoGangGroup ? event.deviceId : twoGangId,
|
||||
code: 'switch_1',
|
||||
value: !event.value),
|
||||
twoGangGroup ? event.deviceId : twoGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: twoGangGroup));
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
add(InitialEvent(groupScreen: twoGangGroup));
|
||||
}
|
||||
}
|
||||
|
||||
void _changeSecondSwitch(
|
||||
ChangeSecondSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||
try {
|
||||
deviceStatus.secondSwitch = !event.value;
|
||||
emit(UpdateState(twoGangModel: deviceStatus));
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: twoGangGroup ? event.deviceId : twoGangId,
|
||||
code: 'switch_2',
|
||||
value: !event.value),
|
||||
twoGangGroup ? event.deviceId : twoGangId);
|
||||
|
||||
if (!response['success']) {
|
||||
add(InitialEvent(groupScreen: twoGangGroup));
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
add(InitialEvent(groupScreen: twoGangGroup));
|
||||
}
|
||||
}
|
||||
|
||||
void _allOff(AllOffEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||
|
||||
try {
|
||||
deviceStatus.firstSwitch = false;
|
||||
deviceStatus.secondSwitch = false;
|
||||
emit(UpdateState(twoGangModel: deviceStatus));
|
||||
|
||||
final response = await Future.wait([
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: twoGangId,
|
||||
code: 'switch_1',
|
||||
value: deviceStatus.firstSwitch),
|
||||
twoGangId),
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: twoGangId,
|
||||
code: 'switch_2',
|
||||
value: deviceStatus.secondSwitch),
|
||||
twoGangId),
|
||||
]);
|
||||
|
||||
if (response.every((element) => !element['success'])) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: false));
|
||||
}
|
||||
} catch (_) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: false));
|
||||
}
|
||||
}
|
||||
|
||||
void _allOn(AllOnEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||
try {
|
||||
deviceStatus.firstSwitch = true;
|
||||
deviceStatus.secondSwitch = true;
|
||||
emit(UpdateState(twoGangModel: deviceStatus));
|
||||
final response = await Future.wait([
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: twoGangId,
|
||||
code: 'switch_1',
|
||||
value: deviceStatus.firstSwitch),
|
||||
twoGangId),
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: twoGangId,
|
||||
code: 'switch_2',
|
||||
value: deviceStatus.secondSwitch),
|
||||
twoGangId),
|
||||
]);
|
||||
if (response.every((element) => !element['success'])) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: false));
|
||||
}
|
||||
} catch (_) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: false));
|
||||
}
|
||||
}
|
||||
|
||||
void _groupAllOn(GroupAllOnEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||
try {
|
||||
for (int i = 0; i < groupTwoGangList.length; i++) {
|
||||
groupTwoGangList[i].firstSwitch = true;
|
||||
groupTwoGangList[i].secondSwitch = true;
|
||||
}
|
||||
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: true));
|
||||
|
||||
for (int i = 0; i < groupTwoGangList.length; i++) {
|
||||
final response = await Future.wait([
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: groupTwoGangList[i].deviceId,
|
||||
code: 'switch_1',
|
||||
value: true),
|
||||
groupTwoGangList[i].deviceId),
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: groupTwoGangList[i].deviceId,
|
||||
code: 'switch_2',
|
||||
value: true),
|
||||
groupTwoGangList[i].deviceId),
|
||||
]);
|
||||
|
||||
if (response.every((element) => !element['success'])) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: true));
|
||||
}
|
||||
}
|
||||
|
||||
void _groupAllOff(GroupAllOffEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||
try {
|
||||
for (int i = 0; i < groupTwoGangList.length; i++) {
|
||||
groupTwoGangList[i].firstSwitch = false;
|
||||
groupTwoGangList[i].secondSwitch = false;
|
||||
}
|
||||
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: false));
|
||||
|
||||
for (int i = 0; i < groupTwoGangList.length; i++) {
|
||||
final response = await Future.wait([
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: groupTwoGangList[i].deviceId,
|
||||
code: 'switch_1',
|
||||
value: false),
|
||||
groupTwoGangList[i].deviceId),
|
||||
DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: groupTwoGangList[i].deviceId,
|
||||
code: 'switch_2',
|
||||
value: false),
|
||||
groupTwoGangList[i].deviceId),
|
||||
]);
|
||||
|
||||
if (response.every((element) => !element['success'])) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(const InitialEvent(groupScreen: true));
|
||||
}
|
||||
}
|
||||
|
||||
void _changeSliding(
|
||||
ChangeSlidingSegment event, Emitter<TwoGangState> emit) async {
|
||||
emit(ChangeSlidingSegmentState(value: event.value));
|
||||
}
|
||||
|
||||
void _setCounterValue(
|
||||
SetCounterValue event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||
int seconds = 0;
|
||||
try {
|
||||
seconds = event.duration.inSeconds;
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: twoGangId,
|
||||
code: event.deviceCode,
|
||||
value: seconds),
|
||||
twoGangId);
|
||||
|
||||
if (response['success'] ?? false) {
|
||||
if (event.deviceCode == 'countdown_1') {
|
||||
deviceStatus.firstCountDown = seconds;
|
||||
}
|
||||
else if (event.deviceCode == 'countdown_2') {
|
||||
deviceStatus.secondCountDown = seconds;
|
||||
}
|
||||
} else {
|
||||
emit(const FailedState(error: 'Something went wrong'));
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
if (seconds > 0) {
|
||||
_onStartTimer(seconds);
|
||||
} else {
|
||||
_timer?.cancel();
|
||||
emit(TimerRunComplete());
|
||||
}
|
||||
}
|
||||
|
||||
void _getCounterValue(
|
||||
GetCounterEvent event, Emitter<TwoGangState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
try {
|
||||
add(GetScheduleEvent());
|
||||
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
||||
List<StatusModel> statusModelList = [];
|
||||
for (var status in response['status']) {
|
||||
statusModelList.add(StatusModel.fromJson(status));
|
||||
}
|
||||
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
||||
|
||||
if (event.deviceCode == 'countdown_1') {
|
||||
deviceStatus.firstCountDown > 0
|
||||
? _onStartTimer(deviceStatus.firstCountDown)
|
||||
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
|
||||
} else if (event.deviceCode == 'countdown_2') {
|
||||
deviceStatus.secondCountDown > 0
|
||||
? _onStartTimer(deviceStatus.secondCountDown)
|
||||
: emit(UpdateTimerState(seconds: deviceStatus.secondCountDown));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void _onClose(OnClose event, Emitter<TwoGangState> emit) {
|
||||
_timer?.cancel();
|
||||
}
|
||||
|
||||
void _onStartTimer(int seconds) {
|
||||
_timer?.cancel();
|
||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
add(TickTimer(seconds - timer.tick));
|
||||
});
|
||||
}
|
||||
|
||||
void _onTickTimer(TickTimer event, Emitter<TwoGangState> emit) {
|
||||
if (event.remainingTime > 0) {
|
||||
emit(TimerRunInProgress(event.remainingTime));
|
||||
} else {
|
||||
_timer?.cancel();
|
||||
emit(TimerRunComplete());
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, String>> days = [
|
||||
{"day": "Sun", "key": "Sun"},
|
||||
{"day": "Mon", "key": "Mon"},
|
||||
{"day": "Tue", "key": "Tue"},
|
||||
{"day": "Wed", "key": "Wed"},
|
||||
{"day": "Thu", "key": "Thu"},
|
||||
{"day": "Fri", "key": "Fri"},
|
||||
{"day": "Sat", "key": "Sat"},
|
||||
];
|
||||
|
||||
Future<void> toggleDaySelection(
|
||||
ToggleDaySelectionEvent event,
|
||||
Emitter<TwoGangState> emit,
|
||||
) async {
|
||||
emit(LoadingInitialState());
|
||||
if (selectedDays.contains(event.key)) {
|
||||
selectedDays.remove(event.key);
|
||||
} else {
|
||||
selectedDays.add(event.key);
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
add(ChangeSlidingSegment(value: 1));
|
||||
}
|
||||
|
||||
Future<void> saveSchedule(TwoGangSave event, Emitter<TwoGangState> emit,) async {
|
||||
try {
|
||||
if(selectedDays.isNotEmpty) {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.postSchedule(
|
||||
category: switchCode,
|
||||
deviceId: twoGangId,
|
||||
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||
code: switchCode,
|
||||
value: toggleSchedule,
|
||||
days: selectedDays);
|
||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||
add(GetScheduleEvent());
|
||||
emit(TwoGangSaveSchedule());
|
||||
toggleCreateSchedule();
|
||||
}else{
|
||||
CustomSnackBar.displaySnackBar('Please select days');
|
||||
}
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getSchedule(GetScheduleEvent event, Emitter<TwoGangState> emit,) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.getSchedule(
|
||||
category: switchCode,
|
||||
deviceId: twoGangId,
|
||||
);
|
||||
List<dynamic> jsonData = response;
|
||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||
emit(InitialState());
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||
if (dateTime == null) return null;
|
||||
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||
dateTime.day, dateTime.hour, dateTime.minute);
|
||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||
}
|
||||
|
||||
Future toggleRepeat(
|
||||
ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.changeSchedule(
|
||||
scheduleId: event.id,
|
||||
deviceUuid: twoGangId,
|
||||
enable: event.toggle);
|
||||
if (response == true) {
|
||||
add(GetScheduleEvent());
|
||||
toggleSchedule = event.toggle;
|
||||
return toggleSchedule;
|
||||
}
|
||||
emit(IsToggleState(onOff: toggleSchedule));
|
||||
add(const ChangeSlidingSegment(value: 1));
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future deleteSchedule(
|
||||
DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
|
||||
try {
|
||||
emit(LoadingInitialState());
|
||||
final response = await DevicesAPI.deleteSchedule(
|
||||
scheduleId: event.id,
|
||||
deviceUuid: twoGangId, );
|
||||
if (response == true) {
|
||||
add(GetScheduleEvent());
|
||||
return toggleSchedule;
|
||||
}
|
||||
emit(IsToggleState(onOff: toggleSchedule));
|
||||
add(const ChangeSlidingSegment(value: 1));
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage = errorData['message'];
|
||||
emit(FailedState(error: errorMessage.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,130 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class TwoGangEvent extends Equatable {
|
||||
const TwoGangEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class LoadingEvent extends TwoGangEvent {}
|
||||
|
||||
class TwoGangUpdated extends TwoGangEvent {}
|
||||
class TwoGangSave extends TwoGangEvent {}
|
||||
class ToggleScheduleEvent extends TwoGangEvent {
|
||||
final String id;
|
||||
final bool toggle;
|
||||
const ToggleScheduleEvent({required this.toggle,required this.id});
|
||||
@override
|
||||
List<Object> get props => [toggle,id];
|
||||
}
|
||||
class errorMessage extends TwoGangEvent {}
|
||||
class ToggleDaySelectionEvent extends TwoGangEvent {
|
||||
|
||||
final String key;
|
||||
|
||||
const ToggleDaySelectionEvent({required this.key});
|
||||
@override
|
||||
List<Object> get props => [key];
|
||||
}
|
||||
|
||||
class InitialEvent extends TwoGangEvent {
|
||||
final bool groupScreen;
|
||||
const InitialEvent({required this.groupScreen});
|
||||
@override
|
||||
List<Object> get props => [groupScreen];
|
||||
}
|
||||
|
||||
class ChangeFirstSwitchStatusEvent extends TwoGangEvent {
|
||||
final bool value;
|
||||
final String deviceId;
|
||||
const ChangeFirstSwitchStatusEvent({required this.value, this.deviceId = ''});
|
||||
@override
|
||||
List<Object> get props => [value, deviceId];
|
||||
}
|
||||
|
||||
class ChangeSecondSwitchStatusEvent extends TwoGangEvent {
|
||||
final bool value;
|
||||
final String deviceId;
|
||||
const ChangeSecondSwitchStatusEvent({required this.value, this.deviceId = ''});
|
||||
@override
|
||||
List<Object> get props => [value, deviceId];
|
||||
}
|
||||
|
||||
|
||||
class AllOffEvent extends TwoGangEvent {}
|
||||
|
||||
class AllOnEvent extends TwoGangEvent {}
|
||||
|
||||
class GroupAllOnEvent extends TwoGangEvent {}
|
||||
|
||||
class GroupAllOffEvent extends TwoGangEvent {}
|
||||
|
||||
|
||||
// two_gang_event.dart
|
||||
class ToggleCreateScheduleEvent extends TwoGangEvent {}
|
||||
|
||||
|
||||
|
||||
|
||||
class ChangeSlidingSegment extends TwoGangEvent {
|
||||
final int value;
|
||||
const ChangeSlidingSegment({required this.value});
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
}
|
||||
|
||||
class GetCounterEvent extends TwoGangEvent {
|
||||
final String deviceCode;
|
||||
const GetCounterEvent({required this.deviceCode});
|
||||
@override
|
||||
List<Object> get props => [deviceCode];
|
||||
}
|
||||
|
||||
class SetCounterValue extends TwoGangEvent {
|
||||
final Duration duration;
|
||||
final String deviceCode;
|
||||
const SetCounterValue({required this.duration, required this.deviceCode});
|
||||
@override
|
||||
List<Object> get props => [duration, deviceCode];
|
||||
}
|
||||
|
||||
class StartTimer extends TwoGangEvent {
|
||||
final int duration;
|
||||
|
||||
const StartTimer(this.duration);
|
||||
|
||||
@override
|
||||
List<Object> get props => [duration];
|
||||
}
|
||||
|
||||
class TickTimer extends TwoGangEvent {
|
||||
final int remainingTime;
|
||||
|
||||
const TickTimer(this.remainingTime);
|
||||
|
||||
@override
|
||||
List<Object> get props => [remainingTime];
|
||||
}
|
||||
|
||||
class StopTimer extends TwoGangEvent {}
|
||||
|
||||
class OnClose extends TwoGangEvent {}
|
||||
|
||||
|
||||
class GetScheduleEvent extends TwoGangEvent {}
|
||||
class DeleteScheduleEvent extends TwoGangEvent {
|
||||
final String id;
|
||||
const DeleteScheduleEvent({required this.id});
|
||||
@override
|
||||
List<Object> get props => [id];
|
||||
}
|
||||
class TabChangedEvent extends TwoGangEvent {
|
||||
final int index;
|
||||
TabChangedEvent({required this.index});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.dart';
|
||||
import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
|
||||
|
||||
|
||||
class TwoGangState extends Equatable {
|
||||
const TwoGangState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class InitialState extends TwoGangState {}
|
||||
class TwoGangSaveSchedule extends TwoGangState {}
|
||||
class ChangeTimeState extends TwoGangState {}
|
||||
|
||||
class LoadingInitialState extends TwoGangState {}
|
||||
|
||||
class UpdateState extends TwoGangState {
|
||||
final TwoGangModel twoGangModel;
|
||||
const UpdateState({required this.twoGangModel});
|
||||
|
||||
@override
|
||||
List<Object> get props => [TwoGangModel];
|
||||
}
|
||||
|
||||
class LoadingNewSate extends TwoGangState {
|
||||
final TwoGangModel twoGangModel;
|
||||
const LoadingNewSate({required this.twoGangModel});
|
||||
|
||||
@override
|
||||
List<Object> get props => [TwoGangModel];
|
||||
}
|
||||
|
||||
class UpdateGroupState extends TwoGangState {
|
||||
final List<GroupTwoGangModel> twoGangList;
|
||||
final bool allSwitches;
|
||||
|
||||
const UpdateGroupState({required this.twoGangList, required this.allSwitches});
|
||||
|
||||
@override
|
||||
List<Object> get props => [twoGangList, allSwitches];
|
||||
}
|
||||
|
||||
class FailedState extends TwoGangState {
|
||||
final String error;
|
||||
|
||||
const FailedState({required this.error});
|
||||
|
||||
@override
|
||||
List<Object> get props => [error];
|
||||
}
|
||||
|
||||
class ChangeSlidingSegmentState extends TwoGangState {
|
||||
final int value;
|
||||
|
||||
const ChangeSlidingSegmentState({required this.value});
|
||||
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
}
|
||||
|
||||
class UpdateTimerState extends TwoGangState {
|
||||
final int seconds;
|
||||
const UpdateTimerState({required this.seconds});
|
||||
|
||||
@override
|
||||
List<Object> get props => [seconds];
|
||||
}
|
||||
|
||||
class TimerRunInProgress extends TwoGangState {
|
||||
final int remainingTime;
|
||||
|
||||
const TimerRunInProgress(this.remainingTime);
|
||||
|
||||
@override
|
||||
List<Object> get props => [remainingTime];
|
||||
}
|
||||
|
||||
class TimerRunComplete extends TwoGangState {}
|
||||
class IsToggleState extends TwoGangState {
|
||||
final bool? onOff;
|
||||
const IsToggleState({this.onOff});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// two_gang_state.dart
|
||||
class UpdateCreateScheduleState extends TwoGangState {
|
||||
final bool createSchedule;
|
||||
UpdateCreateScheduleState(this.createSchedule);
|
||||
}
|
||||
@ -58,10 +58,6 @@ class DeviceModel {
|
||||
tempIcon = Assets.assetsIcons3GangSwitch;
|
||||
} else if (type == DeviceType.Gateway) {
|
||||
tempIcon = Assets.assetsIconsGateway;
|
||||
} else if (type == DeviceType.OneGang) {
|
||||
tempIcon = Assets.oneGang;
|
||||
} else if (type == DeviceType.TwoGang) {
|
||||
tempIcon = Assets.twoGang;
|
||||
} else {
|
||||
tempIcon = Assets.assetsIconsLogo;
|
||||
}
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
class GroupTwoGangModel {
|
||||
final String deviceId;
|
||||
final String deviceName;
|
||||
bool firstSwitch;
|
||||
bool secondSwitch;
|
||||
|
||||
GroupTwoGangModel({
|
||||
required this.deviceId,
|
||||
required this.deviceName,
|
||||
required this.firstSwitch,
|
||||
required this.secondSwitch,
|
||||
});
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
|
||||
class OneGangModel {
|
||||
bool firstSwitch;
|
||||
int firstCountDown;
|
||||
|
||||
OneGangModel(
|
||||
{required this.firstSwitch,
|
||||
required this.firstCountDown,
|
||||
});
|
||||
|
||||
factory OneGangModel.fromJson(List<StatusModel> jsonList) {
|
||||
late bool _switch;
|
||||
late int _count;
|
||||
|
||||
|
||||
for (int i = 0; i < jsonList.length; i++) {
|
||||
if (jsonList[i].code == 'switch_1') {
|
||||
_switch = jsonList[i].value ?? false;
|
||||
} else if (jsonList[i].code == 'countdown_1') {
|
||||
_count = jsonList[i].value ?? 0;
|
||||
}
|
||||
}
|
||||
return OneGangModel(
|
||||
firstSwitch: _switch,
|
||||
firstCountDown: _count,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,83 +0,0 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class ScheduleModel {
|
||||
String category;
|
||||
bool enable;
|
||||
ScheduleFunctionData function;
|
||||
String time;
|
||||
String scheduleId;
|
||||
String timezoneId;
|
||||
List<String> days;
|
||||
|
||||
ScheduleModel({
|
||||
required this.category,
|
||||
required this.enable,
|
||||
required this.function,
|
||||
required this.time,
|
||||
required this.scheduleId,
|
||||
required this.timezoneId,
|
||||
required this.days,
|
||||
});
|
||||
|
||||
// Factory method to create an instance from JSON
|
||||
factory ScheduleModel.fromJson(Map<String, dynamic> json) {
|
||||
return ScheduleModel(
|
||||
category: json['category'],
|
||||
enable: json['enable'],
|
||||
function: ScheduleFunctionData.fromJson(json['function']),
|
||||
time:getTimeIn12HourFormat( json['time']),
|
||||
scheduleId: json['scheduleId'],
|
||||
timezoneId: json['timezoneId'],
|
||||
days: List<String>.from(json['days']),
|
||||
);
|
||||
}
|
||||
|
||||
// Method to convert an instance into JSON
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'category': category,
|
||||
'enable': enable,
|
||||
'function': function.toJson(),
|
||||
'time': time,
|
||||
'scheduleId': scheduleId,
|
||||
'timezoneId': timezoneId,
|
||||
'days': days,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ScheduleFunctionData {
|
||||
String code;
|
||||
bool value;
|
||||
|
||||
ScheduleFunctionData({
|
||||
required this.code,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
// Factory method to create an instance from JSON
|
||||
factory ScheduleFunctionData.fromJson(Map<String, dynamic> json) {
|
||||
return ScheduleFunctionData(
|
||||
code: json['code'],
|
||||
value: json['value'],
|
||||
);
|
||||
}
|
||||
|
||||
// Method to convert an instance into JSON
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'code': code,
|
||||
'value': value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
String getTimeIn12HourFormat(time) {
|
||||
// Parse the time string (in HH:mm format)
|
||||
final DateFormat inputFormat = DateFormat("HH:mm");
|
||||
final DateFormat outputFormat = DateFormat("h:mm a"); // 12-hour format with AM/PM
|
||||
|
||||
// Convert the time string
|
||||
DateTime parsedTime = inputFormat.parse(time);
|
||||
return outputFormat.format(parsedTime);
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
|
||||
class TwoGangModel {
|
||||
bool firstSwitch;
|
||||
bool secondSwitch;
|
||||
int firstCountDown;
|
||||
int secondCountDown;
|
||||
|
||||
TwoGangModel(
|
||||
{required this.firstSwitch,
|
||||
required this.secondSwitch,
|
||||
required this.firstCountDown,
|
||||
required this.secondCountDown,
|
||||
});
|
||||
|
||||
factory TwoGangModel.fromJson(List<StatusModel> jsonList) {
|
||||
late bool _firstSwitch;
|
||||
late bool _secondSwitch;
|
||||
late int _firstCount;
|
||||
late int _secondCount;
|
||||
|
||||
for (int i = 0; i < jsonList.length; i++) {
|
||||
if (jsonList[i].code == 'switch_1') {
|
||||
_firstSwitch = jsonList[i].value ?? false;
|
||||
} else if (jsonList[i].code == 'switch_2') {
|
||||
_secondSwitch = jsonList[i].value ?? false;
|
||||
}else if (jsonList[i].code == 'countdown_1') {
|
||||
_firstCount = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'countdown_2') {
|
||||
_secondCount = jsonList[i].value ?? 0;
|
||||
}
|
||||
}
|
||||
return TwoGangModel(
|
||||
firstSwitch: _firstSwitch,
|
||||
secondSwitch: _secondSwitch,
|
||||
firstCountDown: _firstCount,
|
||||
secondCountDown: _secondCount,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -79,7 +79,8 @@ class DevicesViewBody extends StatelessWidget {
|
||||
),
|
||||
if (HomeCubit.getInstance().selectedSpace != null)
|
||||
if (HomeCubit.getInstance().selectedSpace!.rooms != null)
|
||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map((room) {
|
||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map(
|
||||
(room) {
|
||||
return RoomPage(
|
||||
room: room,
|
||||
);
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_screen.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class OneGangInterface extends StatelessWidget {
|
||||
const OneGangInterface({super.key, this.gangSwitch});
|
||||
|
||||
final DeviceModel? gangSwitch;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: gangSwitch != null
|
||||
? DeviceAppbar(
|
||||
deviceName: gangSwitch!.name!,
|
||||
deviceUuid: gangSwitch!.uuid!,
|
||||
)
|
||||
: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: BodyLarge(
|
||||
text: gangSwitch?.name ?? 'Lights',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.assetsImagesBackground,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: Constants.defaultPadding,
|
||||
right: Constants.defaultPadding,
|
||||
bottom: Constants.bottomNavBarHeight,
|
||||
),
|
||||
child: OneGangScreen(device: gangSwitch),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,171 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/one_gang_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_timer_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/gang_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.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 '../../../bloc/one_gang_bloc/one_gang_event.dart';
|
||||
|
||||
class OneGangScreen extends StatelessWidget {
|
||||
const OneGangScreen({super.key, this.device});
|
||||
|
||||
final DeviceModel? device;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => OneGangBloc(
|
||||
switchCode: 'switch_1',
|
||||
oneGangId : device?.uuid ?? '')
|
||||
..add(const InitialEvent(groupScreen:false)),
|
||||
child: BlocBuilder<OneGangBloc, OneGangState>(
|
||||
builder: (context, state) {
|
||||
OneGangModel oneGangModel = OneGangModel(
|
||||
firstSwitch: false,
|
||||
firstCountDown: 0,
|
||||
);
|
||||
|
||||
if (state is LoadingNewSate) {
|
||||
oneGangModel = state.oneGangModel;
|
||||
} else if (state is UpdateState) {
|
||||
oneGangModel = state.oneGangModel;
|
||||
}
|
||||
return state is LoadingInitialState ?
|
||||
const Center(
|
||||
child:
|
||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||
):
|
||||
RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
BlocProvider.of<OneGangBloc>(context)
|
||||
.add(InitialEvent(groupScreen: device != null ? false : true));
|
||||
},
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Expanded(child: SizedBox.shrink()),
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
GangSwitch(
|
||||
threeGangSwitch: device!,
|
||||
value: oneGangModel.firstSwitch,
|
||||
action: () {
|
||||
BlocProvider.of<OneGangBloc>(context).add(
|
||||
ChangeFirstSwitchStatusEvent(
|
||||
value: oneGangModel.firstSwitch));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 70,
|
||||
child: BodySmall(
|
||||
text:" Entrance Light",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||
switchCode:'switch_1' ,
|
||||
device: device!,
|
||||
deviceCode: 'countdown_1',
|
||||
)));
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.access_time,
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "Timer",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: SizedBox())
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,258 +0,0 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/create_schedule.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/schedule_list.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.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 TimerScheduleScreen extends StatelessWidget {
|
||||
final DeviceModel device;
|
||||
final String deviceCode;
|
||||
final String switchCode;
|
||||
const TimerScheduleScreen(
|
||||
{required this.device,
|
||||
required this.deviceCode,
|
||||
required this.switchCode,
|
||||
super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: BlocProvider(
|
||||
create: (context) =>
|
||||
OneGangBloc(switchCode: switchCode, oneGangId: device.uuid ?? '')
|
||||
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||
..add(GetScheduleEvent()),
|
||||
child: BlocBuilder<OneGangBloc, OneGangState>(
|
||||
builder: (context, state) {
|
||||
final oneGangBloc = BlocProvider.of<OneGangBloc>(context);
|
||||
Duration duration = Duration.zero;
|
||||
int countNum = 0;
|
||||
if (state is UpdateTimerState) {
|
||||
countNum = state.seconds;
|
||||
} else if (state is TimerRunInProgress) {
|
||||
countNum = state.remainingTime;
|
||||
} else if (state is TimerRunComplete) {
|
||||
countNum = 0;
|
||||
} else if (state is LoadingNewSate) {
|
||||
countNum = 0;
|
||||
}
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (didPop) {
|
||||
if (!didPop) {
|
||||
oneGangBloc.add(OnClose());
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: DefaultScaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: const BodyLarge(
|
||||
text: 'Schedule',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
actions: [
|
||||
oneGangBloc.createSchedule == true ?
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
oneGangBloc.add(ThreeGangSave());
|
||||
},
|
||||
child: const Text('Save')
|
||||
) :
|
||||
oneGangBloc.selectedTabIndex==1? IconButton(
|
||||
onPressed: () {
|
||||
oneGangBloc.toggleCreateSchedule();
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
):SizedBox(),
|
||||
],
|
||||
),
|
||||
child:
|
||||
state is LoadingInitialState?
|
||||
const Center(child: CircularProgressIndicator()):
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
decoration: const ShapeDecoration(
|
||||
color: ColorsManager.onPrimaryColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
),
|
||||
),
|
||||
child: TabBar(
|
||||
onTap: (value) {
|
||||
if(value==0){
|
||||
if(oneGangBloc.createSchedule == true){
|
||||
oneGangBloc.toggleCreateSchedule();
|
||||
}
|
||||
oneGangBloc.toggleSelectedIndex(0);
|
||||
}else{
|
||||
oneGangBloc.toggleSelectedIndex(1);
|
||||
}
|
||||
},
|
||||
indicatorColor: Colors.white, // Customize the indicator
|
||||
dividerHeight: 0,
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
indicator: const ShapeDecoration(
|
||||
color: ColorsManager.slidingBlueColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
),
|
||||
tabs: [
|
||||
Tab(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10),
|
||||
child: BodySmall(
|
||||
text: 'Countdown',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Tab(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Schedule',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
children: [
|
||||
Center(
|
||||
child: Container(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
countNum > 0
|
||||
? BodyLarge(
|
||||
text: _formatDuration(countNum),
|
||||
fontColor:
|
||||
ColorsManager.slidingBlueColor,
|
||||
fontSize: 40,
|
||||
)
|
||||
: CupertinoTimerPicker(
|
||||
mode: CupertinoTimerPickerMode.hm,
|
||||
onTimerDurationChanged:
|
||||
(Duration newDuration) {
|
||||
duration = newDuration;
|
||||
},
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (state is LoadingNewSate) {
|
||||
return;
|
||||
}
|
||||
if (countNum > 0) {
|
||||
oneGangBloc.add(SetCounterValue(
|
||||
deviceCode: deviceCode,
|
||||
duration: Duration.zero));
|
||||
} else if (duration != Duration.zero) {
|
||||
oneGangBloc.add(SetCounterValue(
|
||||
deviceCode: deviceCode,
|
||||
duration: duration));
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(countNum > 0
|
||||
? Assets.pauseIcon
|
||||
: Assets.playIcon)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment:oneGangBloc.listSchedule.isNotEmpty?
|
||||
MainAxisAlignment.start:MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
child: oneGangBloc.createSchedule == true ?
|
||||
CreateSchedule(
|
||||
onToggleChanged: (bool isOn) {
|
||||
oneGangBloc.toggleSchedule = isOn;
|
||||
},
|
||||
onDateTimeChanged: (DateTime dateTime) {
|
||||
oneGangBloc.selectedTime=dateTime;
|
||||
},
|
||||
days: oneGangBloc.days,
|
||||
selectDays: (List<String> selectedDays) {
|
||||
oneGangBloc.selectedDays = selectedDays;
|
||||
},
|
||||
)
|
||||
:
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: ScheduleListView(
|
||||
listSchedule: oneGangBloc.listSchedule, // Pass the schedule list here
|
||||
onDismissed: (scheduleId) {
|
||||
oneGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
||||
oneGangBloc.add(DeleteScheduleEvent(id: scheduleId));
|
||||
},
|
||||
onToggleSchedule: (scheduleId, isEnabled) {
|
||||
oneGangBloc.add(ToggleScheduleEvent(
|
||||
id: scheduleId,
|
||||
toggle: isEnabled,
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDuration(int seconds) {
|
||||
final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
||||
final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||
final secs = (seconds % 60).toString().padLeft(2, '0');
|
||||
return '$hours:$minutes:$secs';
|
||||
}
|
||||
}
|
||||
@ -11,10 +11,6 @@ import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interface.dart';
|
||||
@ -130,24 +126,13 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
||||
break;
|
||||
case DeviceType.LightBulb:
|
||||
navigateToInterface(LightInterface(light: device), context);
|
||||
case DeviceType.OneGang:
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
OneGangInterface(gangSwitch: device)));
|
||||
case DeviceType.TwoGang:
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
TwoGangInterface(gangSwitch: device)));
|
||||
case DeviceType.ThreeGang:
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
ThreeGangInterface(gangSwitch: device)));
|
||||
// navigateToInterface(ThreeGangInterface(gangSwitch: device), context);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@ class RoomsSlider extends StatelessWidget {
|
||||
onPageChanged: (index) {
|
||||
HomeCubit.getInstance().roomSliderPageChanged(index);
|
||||
},
|
||||
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/two_gang_bloc.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/two_gang_state.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
@ -63,8 +63,7 @@ class ScheduleScreen extends StatelessWidget {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||
switchCode :"switch_1",
|
||||
pageBuilder: (context, animation1, animation2) => TimerScreen(
|
||||
device: device,
|
||||
deviceCode: 'countdown_1',
|
||||
)));
|
||||
@ -100,11 +99,10 @@ class ScheduleScreen extends StatelessWidget {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||
switchCode :"switch_2",
|
||||
device: device,
|
||||
deviceCode: 'countdown_2',
|
||||
)));
|
||||
pageBuilder: (context, animation1, animation2) => TimerScreen(
|
||||
device: device,
|
||||
deviceCode: 'countdown_2',
|
||||
)));
|
||||
},
|
||||
child: Container(
|
||||
padding:
|
||||
@ -137,9 +135,8 @@ class ScheduleScreen extends StatelessWidget {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||
switchCode :"switch_3",
|
||||
device: device,
|
||||
pageBuilder: (context, animation1, animation2) => TimerScreen(
|
||||
device: device,
|
||||
deviceCode: 'countdown_3',
|
||||
)));
|
||||
},
|
||||
|
||||
@ -22,9 +22,7 @@ class ThreeGangScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => ThreeGangBloc(
|
||||
switchCode: '',
|
||||
threeGangId: device?.uuid ?? '')
|
||||
create: (context) => ThreeGangBloc(threeGangId: device?.uuid ?? '')
|
||||
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
||||
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||
builder: (context, state) {
|
||||
|
||||
@ -7,10 +7,7 @@ import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_blo
|
||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/create_schedule.dart';
|
||||
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/schedule_list.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
@ -18,17 +15,10 @@ 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 TimerScheduleScreen extends StatelessWidget {
|
||||
class TimerScreen extends StatelessWidget {
|
||||
final DeviceModel device;
|
||||
final String deviceCode;
|
||||
final String switchCode;
|
||||
const TimerScheduleScreen(
|
||||
{required this.device,
|
||||
required this.deviceCode,
|
||||
required this.switchCode,
|
||||
super.key});
|
||||
const TimerScreen({required this.device, required this.deviceCode, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -37,217 +27,150 @@ class TimerScheduleScreen extends StatelessWidget {
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: BlocProvider(
|
||||
create: (context) =>
|
||||
ThreeGangBloc(switchCode: switchCode, threeGangId: device.uuid ?? '')
|
||||
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||
..add(GetScheduleEvent()),
|
||||
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||
builder: (context, state) {
|
||||
final threeGangBloc = BlocProvider.of<ThreeGangBloc>(context);
|
||||
Duration duration = Duration.zero;
|
||||
int countNum = 0;
|
||||
if (state is UpdateTimerState) {
|
||||
countNum = state.seconds;
|
||||
} else if (state is TimerRunInProgress) {
|
||||
countNum = state.remainingTime;
|
||||
} else if (state is TimerRunComplete) {
|
||||
countNum = 0;
|
||||
} else if (state is LoadingNewSate) {
|
||||
countNum = 0;
|
||||
}
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (didPop) {
|
||||
if (!didPop) {
|
||||
threeGangBloc.add(OnClose());
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: DefaultScaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: const BodyLarge(
|
||||
text: 'Schedule',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
actions: [
|
||||
threeGangBloc.createSchedule == true ?
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
threeGangBloc.add(ThreeGangSave());
|
||||
},
|
||||
child: const Text('Save')
|
||||
) :
|
||||
threeGangBloc.selectedTabIndex==1? IconButton(
|
||||
onPressed: () {
|
||||
threeGangBloc.toggleCreateSchedule();
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
):SizedBox(),
|
||||
],
|
||||
),
|
||||
child:
|
||||
state is LoadingInitialState?
|
||||
const Center(child: CircularProgressIndicator()):
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
decoration: const ShapeDecoration(
|
||||
color: ColorsManager.onPrimaryColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
),
|
||||
),
|
||||
child: TabBar(
|
||||
onTap: (value) {
|
||||
if(value==0){
|
||||
if(threeGangBloc.createSchedule == true){
|
||||
threeGangBloc.toggleCreateSchedule();
|
||||
}
|
||||
threeGangBloc.toggleSelectedIndex(0);
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: const BodyLarge(
|
||||
text: 'Schedule',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: BlocProvider(
|
||||
create: (context) => ThreeGangBloc(threeGangId: device.uuid ?? '')
|
||||
..add(GetCounterEvent(deviceCode: deviceCode)),
|
||||
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||
builder: (context, state) {
|
||||
Duration duration = Duration.zero;
|
||||
int countNum = 0;
|
||||
int tabNum = 0;
|
||||
if (state is UpdateTimerState) {
|
||||
countNum = state.seconds;
|
||||
} else if (state is TimerRunInProgress) {
|
||||
countNum = state.remainingTime;
|
||||
} else if (state is TimerRunComplete) {
|
||||
countNum = 0;
|
||||
} else if (state is LoadingNewSate) {
|
||||
countNum = 0;
|
||||
}
|
||||
|
||||
}else{
|
||||
threeGangBloc.toggleSelectedIndex(1);
|
||||
}
|
||||
},
|
||||
indicatorColor: Colors.white, // Customize the indicator
|
||||
dividerHeight: 0,
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
indicator: const ShapeDecoration(
|
||||
color: ColorsManager.slidingBlueColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
),
|
||||
tabs: [
|
||||
Tab(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10),
|
||||
child: BodySmall(
|
||||
text: 'Countdown',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Tab(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Schedule',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (state is ChangeSlidingSegmentState) {
|
||||
tabNum = state.value;
|
||||
}
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (didPop) {
|
||||
if (!didPop) {
|
||||
BlocProvider.of<ThreeGangBloc>(context).add(OnClose());
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.assetsImagesBackground,
|
||||
),
|
||||
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
children: [
|
||||
Center(
|
||||
child: Container(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
countNum > 0
|
||||
? BodyLarge(
|
||||
text: _formatDuration(countNum),
|
||||
fontColor:
|
||||
ColorsManager.slidingBlueColor,
|
||||
fontSize: 40,
|
||||
)
|
||||
: CupertinoTimerPicker(
|
||||
mode: CupertinoTimerPickerMode.hm,
|
||||
onTimerDurationChanged:
|
||||
(Duration newDuration) {
|
||||
duration = newDuration;
|
||||
},
|
||||
),
|
||||
child: state is LoadingInitialState || state is LoadingNewSate
|
||||
? const Center(
|
||||
child: DefaultContainer(
|
||||
width: 50, height: 50, child: CircularProgressIndicator()),
|
||||
)
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: const ShapeDecoration(
|
||||
color: ColorsManager.slidingBlueColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
),
|
||||
child: CupertinoSlidingSegmentedControl<int>(
|
||||
thumbColor: ColorsManager.slidingBlueColor,
|
||||
onValueChanged: (value) {
|
||||
BlocProvider.of<ThreeGangBloc>(context)
|
||||
.add(ChangeSlidingSegment(value: value ?? 0));
|
||||
},
|
||||
groupValue:
|
||||
state is ChangeSlidingSegmentState ? state.value : 0,
|
||||
backgroundColor: Colors.white,
|
||||
children: <int, Widget>{
|
||||
0: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: BodySmall(
|
||||
text: 'Countdown',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (state is LoadingNewSate) {
|
||||
return;
|
||||
}
|
||||
if (countNum > 0) {
|
||||
threeGangBloc.add(SetCounterValue(
|
||||
1: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Schedule',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
if (tabNum == 0)
|
||||
countNum > 0
|
||||
? BodyLarge(
|
||||
text: _formatDuration(countNum),
|
||||
fontColor: ColorsManager.slidingBlueColor,
|
||||
fontSize: 40,
|
||||
)
|
||||
: CupertinoTimerPicker(
|
||||
mode: CupertinoTimerPickerMode.hm,
|
||||
onTimerDurationChanged: (Duration newDuration) {
|
||||
duration = newDuration;
|
||||
},
|
||||
),
|
||||
if (tabNum == 0)
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (state is LoadingNewSate) {
|
||||
return;
|
||||
}
|
||||
if (countNum > 0) {
|
||||
BlocProvider.of<ThreeGangBloc>(context).add(
|
||||
SetCounterValue(
|
||||
deviceCode: deviceCode,
|
||||
duration: Duration.zero));
|
||||
} else if (duration != Duration.zero) {
|
||||
threeGangBloc.add(SetCounterValue(
|
||||
deviceCode: deviceCode,
|
||||
duration: duration));
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(countNum > 0
|
||||
? Assets.pauseIcon
|
||||
: Assets.playIcon)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment:threeGangBloc.listSchedule.isNotEmpty?
|
||||
MainAxisAlignment.start:MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
child: threeGangBloc.createSchedule == true ?
|
||||
CreateSchedule(
|
||||
onToggleChanged: (bool isOn) {
|
||||
threeGangBloc.toggleSchedule = isOn;
|
||||
} else if (duration != Duration.zero) {
|
||||
BlocProvider.of<ThreeGangBloc>(context).add(
|
||||
SetCounterValue(
|
||||
deviceCode: deviceCode, duration: duration));
|
||||
}
|
||||
},
|
||||
onDateTimeChanged: (DateTime dateTime) {
|
||||
threeGangBloc.selectedTime=dateTime;
|
||||
},
|
||||
days: threeGangBloc.days,
|
||||
selectDays: (List<String> selectedDays) {
|
||||
threeGangBloc.selectedDays = selectedDays;
|
||||
},
|
||||
)
|
||||
:
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: ScheduleListView(
|
||||
listSchedule: threeGangBloc.listSchedule, // Pass the schedule list here
|
||||
onDismissed: (scheduleId) {
|
||||
threeGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
||||
threeGangBloc.add(DeleteScheduleEvent(id: scheduleId));
|
||||
},
|
||||
onToggleSchedule: (scheduleId, isEnabled) {
|
||||
threeGangBloc.add(ToggleScheduleEvent(
|
||||
id: scheduleId,
|
||||
toggle: isEnabled,
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
countNum > 0 ? Assets.pauseIcon : Assets.playIcon))
|
||||
],
|
||||
)));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_screen.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class TwoGangInterface extends StatelessWidget {
|
||||
const TwoGangInterface({super.key, this.gangSwitch});
|
||||
|
||||
final DeviceModel? gangSwitch;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: gangSwitch != null
|
||||
? DeviceAppbar(
|
||||
deviceName: gangSwitch!.name!,
|
||||
deviceUuid: gangSwitch!.uuid!,
|
||||
)
|
||||
: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: BodyLarge(
|
||||
text: gangSwitch?.name ?? 'Lights',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.assetsImagesBackground,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: Constants.defaultPadding,
|
||||
right: Constants.defaultPadding,
|
||||
bottom: Constants.bottomNavBarHeight,
|
||||
),
|
||||
child: TwoGangScreen(device: gangSwitch),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.dart';
|
||||
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
|
||||
class TwoGangList extends StatelessWidget {
|
||||
const TwoGangList({super.key, required this.twoGangList, required this.allSwitches});
|
||||
|
||||
final List<GroupTwoGangModel> twoGangList;
|
||||
final bool allSwitches;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||
builder: (context, state) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
const BodySmall(text: 'All Lights'),
|
||||
const SizedBox(height: 5),
|
||||
DevicesDefaultSwitch(
|
||||
switchValue: allSwitches,
|
||||
action: () {
|
||||
BlocProvider.of<ThreeGangBloc>(context).add(GroupAllOnEvent());
|
||||
},
|
||||
secondAction: () {
|
||||
BlocProvider.of<ThreeGangBloc>(context).add(GroupAllOffEvent());
|
||||
},
|
||||
),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.all(0),
|
||||
itemCount: twoGangList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(text: '${twoGangList[index].deviceName} beside light'),
|
||||
const SizedBox(height: 5),
|
||||
DevicesDefaultSwitch(
|
||||
switchValue: twoGangList[index].firstSwitch,
|
||||
action: () {
|
||||
BlocProvider.of<ThreeGangBloc>(context).add(ChangeFirstSwitchStatusEvent(
|
||||
value: twoGangList[index].firstSwitch,
|
||||
deviceId: twoGangList[index].deviceId));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(text: '${twoGangList[index].deviceName} ceiling light'),
|
||||
const SizedBox(height: 5),
|
||||
DevicesDefaultSwitch(
|
||||
switchValue: twoGangList[index].secondSwitch,
|
||||
action: () {
|
||||
BlocProvider.of<ThreeGangBloc>(context).add(ChangeSecondSwitchStatusEvent(
|
||||
value: twoGangList[index].secondSwitch,
|
||||
deviceId: twoGangList[index].deviceId));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(text: '${twoGangList[index].deviceName} spotlight'),
|
||||
const SizedBox(height: 5),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,339 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.dart';
|
||||
import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/gang_switch.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_list.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_schedule_screen.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.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';
|
||||
|
||||
class TwoGangScreen extends StatelessWidget {
|
||||
const TwoGangScreen({super.key, this.device, this.switchCode});
|
||||
final DeviceModel? device;
|
||||
final String? switchCode;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => TwoGangBloc(
|
||||
switchCode: switchCode??'',
|
||||
twoGangId: device?.uuid ?? '')
|
||||
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
||||
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
||||
builder: (context, state) {
|
||||
TwoGangModel twoGangModel = TwoGangModel(
|
||||
firstSwitch: false,
|
||||
secondSwitch: false,
|
||||
firstCountDown: 0,
|
||||
secondCountDown: 0,
|
||||
);
|
||||
|
||||
List<GroupTwoGangModel> groupTwoGangModel = [];
|
||||
bool allSwitchesOn = false;
|
||||
if (state is LoadingNewSate) {
|
||||
twoGangModel = state.twoGangModel;
|
||||
} else if (state is UpdateState) {
|
||||
twoGangModel = state.twoGangModel;
|
||||
} else if (state is UpdateGroupState) {
|
||||
groupTwoGangModel = state.twoGangList;
|
||||
allSwitchesOn = state.allSwitches;
|
||||
}
|
||||
return state is LoadingInitialState
|
||||
? const Center(
|
||||
child: DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),)
|
||||
: device == null
|
||||
? TwoGangList(
|
||||
twoGangList: groupTwoGangModel,
|
||||
allSwitches: allSwitchesOn,
|
||||
)
|
||||
: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
BlocProvider.of<TwoGangBloc>(context)
|
||||
.add(InitialEvent(groupScreen: device != null ? false : true));
|
||||
},
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Expanded(child: SizedBox.shrink()),
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
GangSwitch(
|
||||
threeGangSwitch: device!,
|
||||
value: twoGangModel.firstSwitch,
|
||||
action: () {
|
||||
BlocProvider.of<TwoGangBloc>(context).add(
|
||||
ChangeFirstSwitchStatusEvent(
|
||||
value: twoGangModel.firstSwitch));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 77,
|
||||
child: BodySmall(
|
||||
text: "Cove Light",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
GangSwitch(
|
||||
threeGangSwitch: device!,
|
||||
value: twoGangModel.secondSwitch,
|
||||
action: () {
|
||||
BlocProvider.of<TwoGangBloc>(context).add(
|
||||
ChangeSecondSwitchStatusEvent(
|
||||
value: twoGangModel.secondSwitch));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 77,
|
||||
child: BodySmall(
|
||||
text: "Chandelier",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
BlocProvider.of<TwoGangBloc>(context)
|
||||
.add(AllOnEvent());
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: BodySmall(
|
||||
text: "On",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager
|
||||
.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "All On",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder:
|
||||
(context, animation1, animation2) =>
|
||||
TwoGangScheduleScreen(
|
||||
device: device!,
|
||||
)));
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.access_time,
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "Timer",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: device.uuid,
|
||||
// code: 'switch_1',
|
||||
// value: false,
|
||||
// ),
|
||||
// device.uuid!,
|
||||
// );
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: device.uuid,
|
||||
// code: 'switch_2',
|
||||
// value: false,
|
||||
// ),
|
||||
// device.uuid!,
|
||||
// );
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: device.uuid,
|
||||
// code: 'switch_3',
|
||||
// value: false,
|
||||
// ),
|
||||
// device.uuid!,
|
||||
// );
|
||||
BlocProvider.of<TwoGangBloc>(context)
|
||||
.add(AllOffEvent());
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: BodySmall(
|
||||
text: "Off",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager
|
||||
.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "All Off",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: SizedBox())
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,141 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_timer_screen.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/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.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 TwoGangScheduleScreen extends StatelessWidget {
|
||||
final DeviceModel device;
|
||||
const TwoGangScheduleScreen({required this.device, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: const BodyLarge(
|
||||
text: 'Schedule',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.assetsImagesBackground,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 48,
|
||||
),
|
||||
DefaultContainer(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||
device: device,
|
||||
deviceCode: 'countdown_1',
|
||||
switchCode:'switch_1' ,
|
||||
)));
|
||||
},
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodySmall(
|
||||
text: "Cove Light",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 18,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.dividerColor,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||
device: device,
|
||||
deviceCode: 'countdown_2',
|
||||
switchCode:'switch_2' ,
|
||||
)));
|
||||
},
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodySmall(
|
||||
text: "Chandelier",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 18,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -1,259 +0,0 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/create_schedule.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/schedule_list.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.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:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.dart';
|
||||
|
||||
class TimerScheduleScreen extends StatelessWidget {
|
||||
final DeviceModel device;
|
||||
final String deviceCode;
|
||||
final String switchCode;
|
||||
const TimerScheduleScreen(
|
||||
{required this.device,
|
||||
required this.deviceCode,
|
||||
required this.switchCode,
|
||||
super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: BlocProvider(
|
||||
create: (context) =>
|
||||
TwoGangBloc(switchCode: switchCode, twoGangId: device.uuid ?? '')
|
||||
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||
..add(GetScheduleEvent()),
|
||||
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
||||
builder: (context, state) {
|
||||
final twoGangBloc = BlocProvider.of<TwoGangBloc>(context);
|
||||
Duration duration = Duration.zero;
|
||||
int countNum = 0;
|
||||
if (state is UpdateTimerState) {
|
||||
countNum = state.seconds;
|
||||
} else if (state is TimerRunInProgress) {
|
||||
countNum = state.remainingTime;
|
||||
} else if (state is TimerRunComplete) {
|
||||
countNum = 0;
|
||||
} else if (state is LoadingNewSate) {
|
||||
countNum = 0;
|
||||
}
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (didPop) {
|
||||
if (!didPop) {
|
||||
twoGangBloc.add(OnClose());
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: DefaultScaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: const BodyLarge(
|
||||
text: 'Schedule',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
actions: [
|
||||
twoGangBloc.createSchedule == true ?
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
twoGangBloc.add(TwoGangSave());
|
||||
},
|
||||
child: const Text('Save')
|
||||
) :
|
||||
twoGangBloc.selectedTabIndex==1? IconButton(
|
||||
onPressed: () {
|
||||
twoGangBloc.toggleCreateSchedule();
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
):SizedBox(),
|
||||
],
|
||||
),
|
||||
child:
|
||||
state is LoadingInitialState?
|
||||
const Center(child: CircularProgressIndicator()):
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
decoration: const ShapeDecoration(
|
||||
color: ColorsManager.onPrimaryColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
),
|
||||
),
|
||||
child: TabBar(
|
||||
onTap: (value) {
|
||||
print(value);
|
||||
if(value==0){
|
||||
if(twoGangBloc.createSchedule == true){
|
||||
twoGangBloc.toggleCreateSchedule();
|
||||
}
|
||||
twoGangBloc.toggleSelectedIndex(0);
|
||||
|
||||
}else{
|
||||
twoGangBloc.toggleSelectedIndex(1);
|
||||
}
|
||||
},
|
||||
indicatorColor: Colors.white, // Customize the indicator
|
||||
dividerHeight: 0,
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
indicator: const ShapeDecoration(
|
||||
color: ColorsManager.slidingBlueColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
),
|
||||
tabs: [
|
||||
Tab(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10),
|
||||
child: BodySmall(
|
||||
text: 'Countdown',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Tab(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Schedule',
|
||||
style: context.bodySmall.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
children: [
|
||||
Center(
|
||||
child: Container(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
countNum > 0
|
||||
? BodyLarge(
|
||||
text: _formatDuration(countNum),
|
||||
fontColor:
|
||||
ColorsManager.slidingBlueColor,
|
||||
fontSize: 40,
|
||||
)
|
||||
: CupertinoTimerPicker(
|
||||
mode: CupertinoTimerPickerMode.hm,
|
||||
onTimerDurationChanged:
|
||||
(Duration newDuration) {
|
||||
duration = newDuration;
|
||||
},
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (state is LoadingNewSate) {
|
||||
return;
|
||||
}
|
||||
if (countNum > 0) {
|
||||
twoGangBloc.add(SetCounterValue(
|
||||
deviceCode: deviceCode,
|
||||
duration: Duration.zero));
|
||||
} else if (duration != Duration.zero) {
|
||||
twoGangBloc.add(SetCounterValue(
|
||||
deviceCode: deviceCode,
|
||||
duration: duration));
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(countNum > 0
|
||||
? Assets.pauseIcon
|
||||
: Assets.playIcon)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment:twoGangBloc.listSchedule.isNotEmpty?
|
||||
MainAxisAlignment.start:MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
child: twoGangBloc.createSchedule == true ?
|
||||
CreateSchedule(
|
||||
onToggleChanged: (bool isOn) {
|
||||
twoGangBloc.toggleSchedule = isOn;
|
||||
},
|
||||
onDateTimeChanged: (DateTime dateTime) {
|
||||
twoGangBloc.selectedTime=dateTime;
|
||||
},
|
||||
days: twoGangBloc.days,
|
||||
selectDays: (List<String> selectedDays) {
|
||||
twoGangBloc.selectedDays = selectedDays;
|
||||
},
|
||||
)
|
||||
:
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: ScheduleListView(
|
||||
listSchedule: twoGangBloc.listSchedule, // Pass the schedule list here
|
||||
onDismissed: (scheduleId) {
|
||||
twoGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
||||
twoGangBloc.add(DeleteScheduleEvent(id: scheduleId));
|
||||
},
|
||||
onToggleSchedule: (scheduleId, isEnabled) {
|
||||
twoGangBloc.add(ToggleScheduleEvent(
|
||||
id: scheduleId,
|
||||
toggle: isEnabled,
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDuration(int seconds) {
|
||||
final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
||||
final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||
final secs = (seconds % 60).toString().padLeft(2, '0');
|
||||
return '$hours:$minutes:$secs';
|
||||
}
|
||||
}
|
||||
@ -1,139 +0,0 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class CreateSchedule extends StatefulWidget {
|
||||
final List<Map<String, String>> days;
|
||||
final void Function(List<String> selectedDays)? selectDays; // Callback for selected days
|
||||
final Function(DateTime) onDateTimeChanged;
|
||||
final void Function(bool isOn)? onToggleChanged; // Callback for toggle state
|
||||
|
||||
const CreateSchedule({
|
||||
Key? key,
|
||||
required this.days,
|
||||
required this.selectDays,
|
||||
required this.onDateTimeChanged,
|
||||
this.onToggleChanged, // Optional callback
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CreateScheduleState createState() => _CreateScheduleState();
|
||||
}
|
||||
|
||||
class _CreateScheduleState extends State<CreateSchedule> {
|
||||
List<String> selectedDays = []; // List of selected days
|
||||
bool isOn = true; // Boolean state for the ON/OFF toggle
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
const Divider(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
SizedBox(
|
||||
height: 110,
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
initialDateTime: DateTime.now(),
|
||||
onDateTimeChanged: widget.onDateTimeChanged,
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.08,
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: widget.days.map((day) {
|
||||
bool isSelected = selectedDays.contains(day['day']); // Check if day is selected
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
if (isSelected) {
|
||||
selectedDays.remove(day['day']); // Deselect day
|
||||
} else {
|
||||
selectedDays.add(day['day']!); // Select day
|
||||
}
|
||||
if (widget.selectDays != null) {
|
||||
widget.selectDays!(selectedDays);
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
width: 50,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: isSelected
|
||||
? Colors.black
|
||||
: ColorsManager.grayColor,
|
||||
),
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
day['day']!,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isSelected
|
||||
? Colors.black
|
||||
: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isOn = !isOn; // Toggle the state
|
||||
if (widget.onToggleChanged != null) {
|
||||
widget.onToggleChanged!(isOn); // Pass the new toggle state
|
||||
}
|
||||
});
|
||||
},
|
||||
child: DefaultContainer(
|
||||
height: 60,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
isOn ? 'ON' : 'OFF', // Change text based on state
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
CircleAvatar(
|
||||
backgroundColor: isOn
|
||||
? ColorsManager.secondaryColor.withOpacity(0.6)
|
||||
: Colors.red.withOpacity(0.6), // Change background color based on state
|
||||
child: const Icon(
|
||||
Icons.power_settings_new,
|
||||
color: ColorsManager.onPrimaryColor, // Change icon color
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
|
||||
class EmptySchedule extends StatelessWidget {
|
||||
const EmptySchedule({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 180,
|
||||
width: 180,
|
||||
child: Center(child: Column(
|
||||
children: [
|
||||
Center(
|
||||
child: SvgPicture.asset(
|
||||
height: 100,
|
||||
width: 100,
|
||||
Assets.emptySchedule),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Center(
|
||||
child: Text(
|
||||
'Please add',
|
||||
style: context.displaySmall
|
||||
.copyWith(
|
||||
color: const Color(
|
||||
0XFFD5D5D5),
|
||||
),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Text(
|
||||
'a new schedule',
|
||||
style: context.displaySmall
|
||||
.copyWith(
|
||||
color: const Color(
|
||||
0XFFD5D5D5),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,120 +0,0 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_button.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/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'empty_schedule.dart'; // for SVG icons
|
||||
|
||||
|
||||
class ScheduleListView extends StatelessWidget {
|
||||
final List<ScheduleModel> listSchedule;
|
||||
final Function(String) onDismissed;
|
||||
final Function(String, bool) onToggleSchedule;
|
||||
const ScheduleListView({
|
||||
Key? key,
|
||||
required this.listSchedule,
|
||||
required this.onDismissed,
|
||||
required this.onToggleSchedule,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: listSchedule.isNotEmpty
|
||||
? SizedBox(
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: listSchedule.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Dismissible(
|
||||
key: Key(listSchedule[index].scheduleId),
|
||||
background: Container(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
decoration: const ShapeDecoration(
|
||||
color: Color(0xFFFF0000),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10, right: 10),
|
||||
child: SvgPicture.asset(
|
||||
Assets.assetsDeleteIcon,
|
||||
width: 20,
|
||||
height: 22,
|
||||
),
|
||||
),
|
||||
),
|
||||
direction: DismissDirection.endToStart,
|
||||
onDismissed: (direction) {
|
||||
|
||||
onDismissed(listSchedule[index].scheduleId);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Schedule removed')),
|
||||
);
|
||||
},
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
|
||||
},
|
||||
child: DefaultContainer(
|
||||
padding: const EdgeInsets.all(20),
|
||||
height: MediaQuery.of(context).size.height / 6.4,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
BodyLarge(
|
||||
text: listSchedule[index].time,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontColor: Colors.black,
|
||||
fontSize: 22,
|
||||
),
|
||||
Text(listSchedule[index].days.join(' ')),
|
||||
Text('Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const BodyMedium(
|
||||
text: '',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
trailing: Transform.scale(
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: listSchedule[index].enable,
|
||||
onChanged: (value) {
|
||||
onToggleSchedule(
|
||||
listSchedule[index].scheduleId,
|
||||
value,
|
||||
);
|
||||
},
|
||||
applyTheme: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: const EmptySchedule()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class SuccessDialog extends StatelessWidget {
|
||||
final double dialogWidth;
|
||||
final String message;
|
||||
|
||||
const SuccessDialog(
|
||||
{super.key, this.dialogWidth = 160, required this.message});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
child: Container(
|
||||
width: dialogWidth,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.blackColor.withOpacity(0.7),
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.assetsSuccessWhite,
|
||||
width: 50,
|
||||
height: 50,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
BodySmall(
|
||||
text: message,
|
||||
fontColor: ColorsManager.onPrimaryColor,
|
||||
fontSize: FontSize.s16),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -733,10 +733,6 @@ class Assets {
|
||||
static const String playIcon = "assets/icons/play_ic.svg";
|
||||
static const String gatewayIcon = "assets/icons/gateway_icon.svg";
|
||||
|
||||
//assets/icons/success-white.svg
|
||||
//assets for success white image
|
||||
static const String assetsSuccessWhite ="assets/icons/success-white.svg";
|
||||
|
||||
/// Assets for assetsImagesAutomation
|
||||
/// assets/images/automation.jpg
|
||||
static const String assetsImagesAutomation = "assets/images/automation.jpg";
|
||||
@ -1033,12 +1029,4 @@ class Assets {
|
||||
|
||||
static const String assetsPresenceState =
|
||||
"assets/icons/functions_icons/automation_functions/presence_state.svg";
|
||||
|
||||
//assets/icons/functions_icons/automation_functions/presence_state.svg
|
||||
|
||||
static const String oneGang = "assets/icons/1gang.svg";
|
||||
|
||||
static const String twoGang = "assets/icons/2gang.svg";
|
||||
|
||||
static const String emptySchedule = "assets/icons/emptySchedule.svg";
|
||||
}
|
||||
|
||||
@ -175,12 +175,4 @@ abstract class ApiEndpoints {
|
||||
//multiple-time offline
|
||||
static const String deleteTemporaryPassword =
|
||||
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
||||
|
||||
|
||||
static const String saveSchedule = '/schedule/{deviceUuid}';
|
||||
static const String getSchedule = '/schedule/{deviceUuid}?category={category}';
|
||||
static const String changeSchedule = '/schedule/enable/{deviceUuid}';
|
||||
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||
import 'package:syncrow_app/services/api/http_service.dart';
|
||||
|
||||
import '../../features/devices/model/create_temporary_password_model.dart';
|
||||
|
||||
class DevicesAPI {
|
||||
@ -270,87 +270,4 @@ class DevicesAPI {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> postSchedule({
|
||||
required String category,
|
||||
required String deviceId,
|
||||
required String time,
|
||||
required String code,
|
||||
required bool value,
|
||||
required List<String> days,
|
||||
|
||||
}) async {
|
||||
print( {
|
||||
"category": category,
|
||||
"time": time,
|
||||
"function":{
|
||||
"code": code,
|
||||
"value":value,
|
||||
},
|
||||
"days": days
|
||||
});
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.saveSchedule.replaceAll('{deviceUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
body:
|
||||
jsonEncode({
|
||||
"category": category,
|
||||
"time": time,
|
||||
"function":{
|
||||
"code": code,
|
||||
"value":value,
|
||||
},
|
||||
"days": days
|
||||
},),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future getSchedule({
|
||||
required String category,
|
||||
required String deviceId,
|
||||
}) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getSchedule.replaceAll('{deviceUuid}', deviceId).replaceAll('{category}', category),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<bool> changeSchedule({
|
||||
required String deviceUuid,
|
||||
required String scheduleId,
|
||||
required bool enable,
|
||||
}) async {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.changeSchedule.replaceAll('{deviceUuid}', deviceUuid),
|
||||
body: {
|
||||
"scheduleId": scheduleId,
|
||||
"enable": enable
|
||||
},
|
||||
expectedResponseModel: (json) {
|
||||
return json['success'];
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future deleteSchedule({
|
||||
required String deviceUuid,
|
||||
required String scheduleId,
|
||||
}) async {
|
||||
final response = await _httpService.delete(
|
||||
path: ApiEndpoints.deleteSchedule.replaceAll('{deviceUuid}', deviceUuid).replaceAll('{scheduleId}', scheduleId),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,8 +43,6 @@ enum DeviceType {
|
||||
DoorLock,
|
||||
Curtain,
|
||||
Blind,
|
||||
OneGang,
|
||||
TwoGang,
|
||||
ThreeGang,
|
||||
Gateway,
|
||||
CeilingSensor,
|
||||
@ -70,8 +68,6 @@ Map<String, DeviceType> devicesTypesMap = {
|
||||
"DL": DeviceType.DoorLock,
|
||||
"WPS": DeviceType.WallSensor,
|
||||
"3G": DeviceType.ThreeGang,
|
||||
"2G": DeviceType.TwoGang,
|
||||
"1G": DeviceType.OneGang,
|
||||
"CUR": DeviceType.Curtain,
|
||||
};
|
||||
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
@ -159,33 +155,6 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
FunctionModel(
|
||||
code: 'indicator', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
],
|
||||
DeviceType.OneGang:[
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
],
|
||||
DeviceType.TwoGang:[
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})
|
||||
),
|
||||
FunctionModel(
|
||||
code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})
|
||||
),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})
|
||||
),
|
||||
FunctionModel(
|
||||
code: 'countdown_2',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})
|
||||
),
|
||||
],
|
||||
|
||||
DeviceType.ThreeGang: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
|
||||
Reference in New Issue
Block a user