mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-15 17:47:53 +00:00
Compare commits
10 Commits
sep_bug_fi
...
new_device
Author | SHA1 | Date | |
---|---|---|---|
47f1a9a6cd | |||
7661f54427 | |||
4fabbf7a77 | |||
30dd3a1ee2 | |||
9dbf4b0540 | |||
05d027f8ff | |||
0d49ad5106 | |||
9e5d5c0d84 | |||
92d32e4d84 | |||
0731507d3b |
5
assets/icons/ac_lock.svg
Normal file
5
assets/icons/ac_lock.svg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<svg width="25" height="35" viewBox="0 0 25 35" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.3952 0C7.16271 0.00642578 2.92244 4.24662 2.91602 9.47919V15.3125C2.91602 15.7152 3.2425 16.0417 3.64521 16.0417H6.5619C6.9646 16.0417 7.29109 15.7152 7.29109 15.3125V9.47919C7.29102 6.66019 9.57627 4.375 12.3952 4.375C15.2141 4.375 17.4994 6.66019 17.4994 9.47919V15.3125C17.4994 15.7152 17.8259 16.0417 18.2286 16.0417H21.1452C21.5479 16.0417 21.8744 15.7152 21.8744 15.3125V9.47919C21.868 4.24662 17.6277 0.00642578 12.3952 0Z" fill="#455A64"/>
|
||||||
|
<path d="M3.64581 14.5833H21.1458C23.1593 14.5833 24.7916 16.2155 24.7916 18.2291V31.3541C24.7916 33.3677 23.1593 34.9999 21.1458 34.9999H3.64581C1.63229 34.9999 0 33.3677 0 31.3541V18.2291C0 16.2155 1.63229 14.5833 3.64581 14.5833Z" fill="#2F66D3"/>
|
||||||
|
<path d="M16.0417 22.6041C16.0501 20.5906 14.4248 18.9514 12.4112 18.9429C10.3977 18.9344 8.75851 20.5598 8.75003 22.5733C8.74415 23.9651 9.53118 25.2388 10.7785 25.8562L10.2156 29.7937C10.1592 30.1924 10.4367 30.5613 10.8355 30.6177C10.8692 30.6225 10.9034 30.6249 10.9375 30.6249H13.8542C14.2569 30.629 14.5866 30.3059 14.5907 29.9032C14.591 29.8661 14.5886 29.8289 14.5833 29.7922L14.0203 25.8547C15.2524 25.2381 16.0337 23.9817 16.0417 22.6041Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
28
assets/icons/ac_schedule.svg
Normal file
28
assets/icons/ac_schedule.svg
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M16.6724 33.345C25.8803 33.345 33.3447 25.8805 33.3447 16.6726C33.3447 7.46472 25.8803 0.000244141 16.6724 0.000244141C7.46448 0.000244141 0 7.46472 0 16.6726C0 25.8805 7.46448 33.345 16.6724 33.345Z" fill="#F07281"/>
|
||||||
|
<path d="M17.3767 33.3303C17.1436 33.3401 16.9084 33.345 16.6725 33.345C7.46478 33.345 0 25.8802 0 16.6725C0 7.46478 7.46478 0 16.6725 0C16.9084 0 17.1436 0.00492188 17.3767 0.0147656C8.4957 0.38377 1.40841 7.70068 1.40841 16.6725C1.40841 25.6443 8.4957 32.9613 17.3767 33.3303Z" fill="#EB5569"/>
|
||||||
|
<path d="M16.6726 31.1577C24.6725 31.1577 31.1577 24.6725 31.1577 16.6726C31.1577 8.67269 24.6725 2.1875 16.6726 2.1875C8.67269 2.1875 2.1875 8.67269 2.1875 16.6726C2.1875 24.6725 8.67269 31.1577 16.6726 31.1577Z" fill="#EAF6FF"/>
|
||||||
|
<path d="M17.7291 31.1197C17.3805 31.145 17.0276 31.1577 16.6727 31.1577C8.67269 31.1577 2.1875 24.6725 2.1875 16.6725C2.1875 8.67244 8.67275 2.18726 16.6728 2.18726C17.0277 2.18726 17.3805 2.1999 17.7291 2.22526C10.2221 2.76619 4.30022 9.02743 4.30022 16.6725C4.30022 24.3175 10.2221 30.5788 17.7291 31.1197Z" fill="#D8ECFE"/>
|
||||||
|
<path d="M15.7672 8.23932L16.4138 7.82301C16.5715 7.72143 16.7741 7.72143 16.9319 7.82301L17.5785 8.23932C17.6957 8.31479 17.7666 8.44474 17.7666 8.58419V16.8661H15.5791V8.58419C15.579 8.44474 15.6499 8.31486 15.7672 8.23932Z" fill="#5680A6"/>
|
||||||
|
<path d="M17.377 8.10996L16.9876 8.36063V16.8662H15.5791V8.62163C15.5791 8.45893 15.6617 8.30738 15.7985 8.21933L16.4136 7.82326C16.5714 7.72167 16.774 7.72167 16.9318 7.82326L17.377 8.10996Z" fill="#497090"/>
|
||||||
|
<path d="M23.5067 16.9316L23.1106 17.5467C23.0225 17.6835 22.871 17.7662 22.7083 17.7662H16.6729V15.5789H22.7083C22.871 15.5789 23.0225 15.6615 23.1106 15.7983L23.5067 16.4135C23.6083 16.5712 23.6083 16.7738 23.5067 16.9316Z" fill="#5680A6"/>
|
||||||
|
<path d="M19.6131 16.6725C19.6131 17.0591 19.5384 17.4281 19.4018 17.7662H16.6729V15.5789H19.4018C19.5384 15.9169 19.6131 16.2859 19.6131 16.6725Z" fill="#497090"/>
|
||||||
|
<path d="M16.6723 18.2039C17.5182 18.2039 18.2039 17.5182 18.2039 16.6723C18.2039 15.8264 17.5182 15.1406 16.6723 15.1406C15.8264 15.1406 15.1406 15.8264 15.1406 16.6723C15.1406 17.5182 15.8264 18.2039 16.6723 18.2039Z" fill="#F07281"/>
|
||||||
|
<path d="M17.3765 18.0323C17.166 18.1422 16.9265 18.2042 16.6723 18.2042C15.8265 18.2042 15.1406 17.5183 15.1406 16.6725C15.1406 15.8268 15.8265 15.1409 16.6723 15.1409C16.9265 15.1409 17.166 15.2029 17.3765 15.3127C16.885 15.567 16.549 16.081 16.549 16.6726C16.549 17.2642 16.885 17.7781 17.3765 18.0323Z" fill="#EB5569"/>
|
||||||
|
<path d="M34.5329 28.7151V27.6225C34.5329 27.4043 34.3853 27.2137 34.174 27.1592L32.9876 26.853C32.8555 26.3207 32.6457 25.8193 32.37 25.3617L32.9923 24.3064C33.1032 24.1184 33.0728 23.8793 32.9185 23.7249L32.1459 22.9523C31.9916 22.798 31.7524 22.7676 31.5644 22.8785L30.5091 23.5008C30.0516 23.2251 29.5501 23.0153 29.0178 22.8832L28.7116 21.6968C28.6571 21.4855 28.4665 21.3379 28.2483 21.3379H27.1557C26.9375 21.3379 26.7469 21.4855 26.6924 21.6968L26.3862 22.8832C25.8539 23.0153 25.3525 23.2252 24.8949 23.5008L23.8396 22.8785C23.6516 22.7676 23.4125 22.798 23.2581 22.9523L22.4855 23.7249C22.3313 23.8792 22.3009 24.1184 22.4117 24.3064L23.0341 25.3617C22.7583 25.8193 22.5485 26.3207 22.4164 26.853L21.23 27.1592C21.0188 27.2137 20.8711 27.4043 20.8711 27.6225V28.7151C20.8711 28.9333 21.0188 29.1239 21.23 29.1784L22.4164 29.4846C22.5485 30.0169 22.7584 30.5183 23.0341 30.9759L22.4117 32.0312C22.3008 32.2192 22.3313 32.4583 22.4855 32.6127L23.2581 33.3853C23.4124 33.5396 23.6516 33.5699 23.8396 33.4591L24.8949 32.8368C25.3525 33.1125 25.8539 33.3223 26.3862 33.4544L26.6924 34.6408C26.7469 34.8521 26.9375 34.9997 27.1557 34.9997H28.2483C28.4665 34.9997 28.6571 34.8521 28.7116 34.6408L29.0178 33.4544C29.5501 33.3223 30.0516 33.1124 30.5091 32.8368L31.5644 33.4591C31.7524 33.57 31.9915 33.5396 32.1459 33.3853L32.9185 32.6127C33.0728 32.4584 33.1031 32.2192 32.9923 32.0312L32.37 30.9759C32.6457 30.5183 32.8555 30.0169 32.9876 29.4846L34.174 29.1784C34.3853 29.1239 34.5329 28.9333 34.5329 28.7151Z" fill="#88B4F5"/>
|
||||||
|
<path d="M22.2796 27.252V29.0858L23.8246 29.4844C23.9563 30.0168 24.1662 30.5182 24.4423 30.976L23.6317 32.3506L24.4057 33.1246L23.8391 33.4588C23.6511 33.5696 23.4119 33.5393 23.2576 33.3849L22.4853 32.6127C22.331 32.4584 22.3007 32.2192 22.4115 32.0313L23.0338 30.976C22.7577 30.5182 22.5479 30.0168 22.4162 29.4844L21.23 29.1784C21.0187 29.124 20.8711 28.9333 20.8711 28.7151V27.6226C20.8711 27.4044 21.0187 27.2139 21.2299 27.1593L22.4162 26.8527C22.5479 26.321 22.7577 25.8189 23.0338 25.3619L22.4115 24.3064C22.3007 24.1185 22.331 23.8794 22.4853 23.7251L23.2577 22.9523C23.4119 22.7978 23.6512 22.7675 23.8392 22.8784L24.4057 23.2125L23.6317 23.9872L24.4423 25.3619C24.1662 25.8189 23.9564 26.321 23.8246 26.8527L22.2796 27.252Z" fill="#6EA2F2"/>
|
||||||
|
<path d="M27.7946 33.4542L28.1932 35H27.1555C26.9372 35 26.7466 34.8523 26.6921 34.6409L26.3861 33.4542C26.1361 33.393 25.8924 33.3134 25.6572 33.2176L26.303 32.8367C26.7608 33.1126 27.2622 33.3225 27.7946 33.4542Z" fill="#6EA2F2"/>
|
||||||
|
<path d="M27.1555 21.3379H28.1932L27.7946 22.883C27.2622 23.0154 26.7608 23.2252 26.303 23.5006L25.6572 23.1196C25.8925 23.0245 26.1361 22.945 26.3861 22.883L26.6921 21.6969C26.7466 21.4855 26.9373 21.3379 27.1555 21.3379Z" fill="#6EA2F2"/>
|
||||||
|
<path d="M27.7023 31.4612C29.5205 31.4612 30.9944 29.9873 30.9944 28.1691C30.9944 26.3509 29.5205 24.877 27.7023 24.877C25.8841 24.877 24.4102 26.3509 24.4102 28.1691C24.4102 29.9873 25.8841 31.4612 27.7023 31.4612Z" fill="#5680A6"/>
|
||||||
|
<path d="M28.7581 31.2882C28.4264 31.4009 28.0707 31.4615 27.7017 31.4615C25.8841 31.4615 24.4102 29.9875 24.4102 28.1692C24.4102 26.3509 25.8841 24.877 27.7017 24.877C28.0707 24.877 28.4263 24.9375 28.7581 25.0502C27.4588 25.4903 26.5229 26.7206 26.5229 28.1692C26.5229 29.6178 27.4588 30.8481 28.7581 31.2882Z" fill="#497090"/>
|
||||||
|
<path d="M16.6727 6.19289C16.381 6.19289 16.1445 5.95644 16.1445 5.66475V4.30036C16.1445 4.00867 16.381 3.77222 16.6727 3.77222C16.9644 3.77222 17.2008 4.00867 17.2008 4.30036V5.66468C17.2008 5.95637 16.9644 6.19289 16.6727 6.19289Z" fill="#88B4F5"/>
|
||||||
|
<path d="M16.6727 29.5729C16.381 29.5729 16.1445 29.3365 16.1445 29.0448V27.6805C16.1445 27.3888 16.381 27.1523 16.6727 27.1523C16.9644 27.1523 17.2008 27.3888 17.2008 27.6805V29.0448C17.2008 29.3364 16.9644 29.5729 16.6727 29.5729Z" fill="#88B4F5"/>
|
||||||
|
<path d="M5.66492 17.2006H4.30061C4.00892 17.2006 3.77246 16.9641 3.77246 16.6724C3.77246 16.3807 4.00892 16.1443 4.30061 16.1443H5.66492C5.95661 16.1443 6.19307 16.3807 6.19307 16.6724C6.19307 16.9641 5.95661 17.2006 5.66492 17.2006Z" fill="#88B4F5"/>
|
||||||
|
<path d="M29.0448 17.2006H27.6805C27.3887 17.2006 27.1523 16.9641 27.1523 16.6724C27.1523 16.3807 27.3888 16.1443 27.6805 16.1443H29.0448C29.3366 16.1443 29.5729 16.3807 29.5729 16.6724C29.5729 16.9641 29.3365 17.2006 29.0448 17.2006Z" fill="#88B4F5"/>
|
||||||
|
<path d="M5.95843 23.3868C5.77591 23.3868 5.59838 23.2921 5.50056 23.1226C5.35468 22.87 5.44122 22.547 5.69388 22.4012L6.8754 21.719C7.12785 21.5733 7.45099 21.6597 7.59687 21.9123C7.74275 22.1649 7.6562 22.488 7.40355 22.6338L6.22202 23.3159C6.1389 23.364 6.04805 23.3868 5.95843 23.3868Z" fill="#88B4F5"/>
|
||||||
|
<path d="M26.2065 11.6969C26.0239 11.6969 25.8464 11.6022 25.7486 11.4327C25.6027 11.1801 25.6893 10.8571 25.9419 10.7113L27.1234 10.0291C27.376 9.88328 27.699 9.96976 27.8449 10.2224C27.9908 10.475 27.9042 10.7981 27.6516 10.9439L26.4701 11.626C26.3869 11.6741 26.296 11.6969 26.2065 11.6969Z" fill="#88B4F5"/>
|
||||||
|
<path d="M7.139 11.6967C7.04938 11.6967 6.9586 11.6739 6.8754 11.6259L5.69388 10.9437C5.44122 10.7978 5.35468 10.4748 5.50056 10.2222C5.64637 9.96957 5.96937 9.88296 6.22202 10.0289L7.40355 10.7111C7.6562 10.8569 7.74275 11.1799 7.59687 11.4325C7.49904 11.602 7.32152 11.6967 7.139 11.6967Z" fill="#88B4F5"/>
|
||||||
|
<path d="M10.4858 27.9156C10.3962 27.9156 10.3054 27.8928 10.2222 27.8447C9.96954 27.6988 9.883 27.3758 10.0289 27.1232L10.711 25.9417C10.8568 25.6891 11.1799 25.6024 11.4325 25.7484C11.6852 25.8943 11.7717 26.2173 11.6258 26.4699L10.9437 27.6514C10.8458 27.8208 10.6683 27.9156 10.4858 27.9156Z" fill="#88B4F5"/>
|
||||||
|
<path d="M22.1762 7.66776C22.0866 7.66776 21.9958 7.64492 21.9126 7.59687C21.66 7.45106 21.5734 7.12799 21.7193 6.8754L22.4015 5.69388C22.5473 5.44122 22.8702 5.35468 23.1229 5.50056C23.3755 5.64637 23.4621 5.96944 23.3162 6.22202L22.6341 7.40355C22.5363 7.57301 22.3587 7.66776 22.1762 7.66776Z" fill="#88B4F5"/>
|
||||||
|
<path d="M11.1689 7.66776C10.9864 7.66776 10.8089 7.57301 10.711 7.40355L10.0289 6.22202C9.883 5.96944 9.96954 5.64637 10.2222 5.50056C10.4747 5.35468 10.7979 5.44122 10.9437 5.69388L11.6258 6.8754C11.7717 7.12799 11.6852 7.45106 11.4325 7.59687C11.3494 7.64486 11.2585 7.66776 11.1689 7.66776Z" fill="#88B4F5"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.6 KiB |
20
assets/icons/preferences.svg
Normal file
20
assets/icons/preferences.svg
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<svg width="36" height="33" viewBox="0 0 36 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M32.7404 13.0391H30.5674V19.5582H32.7404C34.5406 19.5582 36 18.0988 36 16.2986C36 14.4984 34.5406 13.0391 32.7404 13.0391Z" fill="#A5A8AB"/>
|
||||||
|
<path d="M30.5674 13.0391H3.25956C1.45934 13.0391 0 14.4984 0 16.2986C0 18.0988 1.45934 19.5582 3.25956 19.5582H30.5674C32.3676 19.5582 33.827 18.0988 33.827 16.2986C33.827 14.4984 32.3676 13.0391 30.5674 13.0391Z" fill="#C2C4C6"/>
|
||||||
|
<path d="M32.7404 15.2119H30.5674V17.385H32.7404C33.3405 17.385 33.8269 16.8985 33.8269 16.2984C33.8269 15.6984 33.3405 15.2119 32.7404 15.2119Z" fill="#414851"/>
|
||||||
|
<path d="M30.5672 15.2119H3.25937C2.65932 15.2119 2.17285 15.6984 2.17285 16.2984C2.17285 16.8985 2.65932 17.385 3.25937 17.385H30.5672C31.1673 17.385 31.6537 16.8985 31.6537 16.2984C31.6537 15.6984 31.1673 15.2119 30.5672 15.2119Z" fill="#62676F"/>
|
||||||
|
<path d="M11.9521 10.8652V21.7304C14.9525 21.7304 17.3847 19.2981 17.3847 16.2978C17.3847 13.2975 14.9525 10.8652 11.9521 10.8652Z" fill="#FCBE64"/>
|
||||||
|
<path d="M15.2117 16.2978C15.2117 13.2975 13.7523 10.8652 11.9521 10.8652C8.95181 10.8652 6.51953 13.2975 6.51953 16.2978C6.51953 19.2981 8.95181 21.7304 11.9521 21.7304C13.7523 21.7304 15.2117 19.2981 15.2117 16.2978Z" fill="#FBDB63"/>
|
||||||
|
<path d="M32.7404 2.17285H30.5674V8.69197H32.7404C34.5406 8.69197 36 7.23263 36 5.43241C36 3.63219 34.5406 2.17285 32.7404 2.17285Z" fill="#A5A8AB"/>
|
||||||
|
<path d="M30.5674 2.17285H3.25956C1.45934 2.17285 0 3.63219 0 5.43241C0 7.23263 1.45934 8.69197 3.25956 8.69197H30.5674C32.3676 8.69197 33.827 7.23263 33.827 5.43241C33.827 3.63219 32.3676 2.17285 30.5674 2.17285Z" fill="#C2C4C6"/>
|
||||||
|
<path d="M32.7404 4.3457H30.5674V6.51874H32.7404C33.3405 6.51874 33.8269 6.03227 33.8269 5.43222C33.8269 4.83217 33.3405 4.3457 32.7404 4.3457Z" fill="#414851"/>
|
||||||
|
<path d="M30.5672 4.3457H3.25937C2.65932 4.3457 2.17285 4.83217 2.17285 5.43222C2.17285 6.03227 2.65932 6.51874 3.25937 6.51874H30.5672C31.1673 6.51874 31.6537 6.03227 31.6537 5.43222C31.6537 4.83217 31.1673 4.3457 30.5672 4.3457Z" fill="#62676F"/>
|
||||||
|
<path d="M24.0479 0V10.8652C27.0482 10.8652 29.4804 8.43291 29.4804 5.4326C29.4804 2.43228 27.0482 0 24.0479 0Z" fill="#FA342D"/>
|
||||||
|
<path d="M27.3074 5.4326C27.3074 2.43228 25.848 0 24.0478 0C21.0475 0 18.6152 2.43228 18.6152 5.4326C18.6152 8.43291 21.0475 10.8652 24.0478 10.8652C25.848 10.8652 27.3074 8.43291 27.3074 5.4326Z" fill="#FE5E49"/>
|
||||||
|
<path d="M32.7404 23.9033H30.5674V30.4224H32.7404C34.5406 30.4224 36 28.9631 36 27.1629C36 25.3627 34.5406 23.9033 32.7404 23.9033Z" fill="#A5A8AB"/>
|
||||||
|
<path d="M30.5674 23.9033H3.25956C1.45934 23.9033 0 25.3627 0 27.1629C0 28.9631 1.45934 30.4224 3.25956 30.4224H30.5674C32.3676 30.4224 33.827 28.9631 33.827 27.1629C33.827 25.3627 32.3676 23.9033 30.5674 23.9033Z" fill="#C2C4C6"/>
|
||||||
|
<path d="M32.7404 26.0762H30.5674V28.2492H32.7404C33.3405 28.2492 33.8269 27.7627 33.8269 27.1627C33.8269 26.5626 33.3405 26.0762 32.7404 26.0762Z" fill="#414851"/>
|
||||||
|
<path d="M30.5672 26.0762H3.25937C2.65932 26.0762 2.17285 26.5626 2.17285 27.1627C2.17285 27.7627 2.65932 28.2492 3.25937 28.2492H30.5672C31.1673 28.2492 31.6537 27.7627 31.6537 27.1627C31.6537 26.5626 31.1673 26.0762 30.5672 26.0762Z" fill="#62676F"/>
|
||||||
|
<path d="M24.0479 21.7295V32.5947C27.0482 32.5947 29.4804 30.1624 29.4804 27.1621C29.4804 24.1618 27.0482 21.7295 24.0479 21.7295Z" fill="#7D99E8"/>
|
||||||
|
<path d="M27.3074 27.1621C27.3074 24.1618 25.848 21.7295 24.0478 21.7295C21.0475 21.7295 18.6152 24.1618 18.6152 27.1621C18.6152 30.1624 21.0475 32.5947 24.0478 32.5947C25.848 32.5947 27.3074 30.1624 27.3074 27.1621Z" fill="#83B3F1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
@ -2,11 +2,11 @@ import 'package:flutter/gestures.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:syncrow_web/services/locator.dart';
|
import 'package:syncrow_web/services/locator.dart';
|
||||||
import 'package:syncrow_web/utils/app_routes.dart';
|
import 'package:syncrow_web/utils/app_routes.dart';
|
||||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
||||||
@ -14,8 +14,7 @@ import 'package:syncrow_web/utils/theme/theme.dart';
|
|||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
try {
|
try {
|
||||||
const environment =
|
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
||||||
String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
|
||||||
await dotenv.load(fileName: '.env.$environment');
|
await dotenv.load(fileName: '.env.$environment');
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
initialSetup();
|
initialSetup();
|
||||||
@ -45,11 +44,9 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
//HomeBloc.fetchUserInfo();
|
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||||
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
|
||||||
BlocProvider<VisitorPasswordBloc>(
|
BlocProvider<VisitorPasswordBloc>(
|
||||||
create: (context) => VisitorPasswordBloc(),
|
create: (context) => VisitorPasswordBloc(),
|
||||||
)
|
)
|
||||||
|
@ -18,6 +18,7 @@ class DefaultButton extends StatelessWidget {
|
|||||||
this.height,
|
this.height,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.borderColor,
|
this.borderColor,
|
||||||
|
this.elevation,
|
||||||
});
|
});
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
@ -33,6 +34,7 @@ class DefaultButton extends StatelessWidget {
|
|||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
final Color? foregroundColor;
|
final Color? foregroundColor;
|
||||||
final Color? borderColor;
|
final Color? borderColor;
|
||||||
|
final double? elevation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -45,7 +47,9 @@ class DefaultButton extends StatelessWidget {
|
|||||||
textStyle: WidgetStateProperty.all(
|
textStyle: WidgetStateProperty.all(
|
||||||
customTextStyle ??
|
customTextStyle ??
|
||||||
Theme.of(context).textTheme.bodySmall!.copyWith(
|
Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
fontSize: 13, color: foregroundColor, fontWeight: FontWeight.normal),
|
fontSize: 13,
|
||||||
|
color: foregroundColor,
|
||||||
|
fontWeight: FontWeight.normal),
|
||||||
),
|
),
|
||||||
foregroundColor: WidgetStateProperty.all(
|
foregroundColor: WidgetStateProperty.all(
|
||||||
isSecondary
|
isSecondary
|
||||||
@ -54,7 +58,8 @@ class DefaultButton extends StatelessWidget {
|
|||||||
? foregroundColor ?? Colors.white
|
? foregroundColor ?? Colors.white
|
||||||
: Colors.black,
|
: Colors.black,
|
||||||
),
|
),
|
||||||
backgroundColor: WidgetStateProperty.resolveWith<Color>((Set<WidgetState> states) {
|
backgroundColor: WidgetStateProperty.resolveWith<Color>(
|
||||||
|
(Set<WidgetState> states) {
|
||||||
return enabled
|
return enabled
|
||||||
? backgroundColor ?? ColorsManager.primaryColor
|
? backgroundColor ?? ColorsManager.primaryColor
|
||||||
: Colors.black.withOpacity(0.2);
|
: Colors.black.withOpacity(0.2);
|
||||||
@ -74,6 +79,7 @@ class DefaultButton extends StatelessWidget {
|
|||||||
minimumSize: WidgetStateProperty.all(
|
minimumSize: WidgetStateProperty.all(
|
||||||
const Size.fromHeight(50),
|
const Size.fromHeight(50),
|
||||||
),
|
),
|
||||||
|
elevation: WidgetStateProperty.all(elevation ?? 0),
|
||||||
),
|
),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: height ?? 50,
|
height: height ?? 50,
|
||||||
|
@ -10,7 +10,9 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_re
|
|||||||
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
class AcDeviceBatchControlView extends StatelessWidget
|
class AcDeviceBatchControlView extends StatelessWidget
|
||||||
@ -46,11 +48,11 @@ class AcDeviceBatchControlView extends StatelessWidget
|
|||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
ToggleWidget(
|
ToggleWidget(
|
||||||
icon: Assets.ac,
|
|
||||||
deviceId: devicesIds.first,
|
deviceId: devicesIds.first,
|
||||||
code: 'switch',
|
code: 'switch',
|
||||||
value: state.status.acSwitch,
|
value: state.status.acSwitch,
|
||||||
label: 'ThermoState',
|
label: 'ThermoState',
|
||||||
|
icon: Assets.ac,
|
||||||
onChange: (value) {
|
onChange: (value) {
|
||||||
context.read<AcBloc>().add(AcBatchControlEvent(
|
context.read<AcBloc>().add(AcBatchControlEvent(
|
||||||
devicesIds: devicesIds,
|
devicesIds: devicesIds,
|
||||||
@ -75,13 +77,63 @@ class AcDeviceBatchControlView extends StatelessWidget
|
|||||||
code: 'level',
|
code: 'level',
|
||||||
devicesIds: devicesIds,
|
devicesIds: devicesIds,
|
||||||
),
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
label: '',
|
||||||
|
labelWidget: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.remove,
|
||||||
|
size: 28,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'06',
|
||||||
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
|
color: ColorsManager.dialogBlueTitle,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'h',
|
||||||
|
style: context.textTheme.bodySmall!
|
||||||
|
.copyWith(color: ColorsManager.blackColor),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'30',
|
||||||
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
|
color: ColorsManager.dialogBlueTitle,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text('m',
|
||||||
|
style: context.textTheme.bodySmall!
|
||||||
|
.copyWith(color: ColorsManager.blackColor)),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: 28,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
value: false,
|
||||||
|
code: 'ac_schedule',
|
||||||
|
deviceId: devicesIds.first,
|
||||||
|
icon: Assets.acSchedule,
|
||||||
|
onChange: (value) {},
|
||||||
|
),
|
||||||
ToggleWidget(
|
ToggleWidget(
|
||||||
deviceId: devicesIds.first,
|
deviceId: devicesIds.first,
|
||||||
code: 'child_lock',
|
code: 'child_lock',
|
||||||
value: state.status.childLock,
|
value: state.status.childLock,
|
||||||
label: 'Child Lock',
|
label: 'Child Lock',
|
||||||
icon:
|
icon: state.status.childLock ? Assets.unlock : Assets.acLock,
|
||||||
state.status.childLock ? Assets.childLock : Assets.unlock,
|
|
||||||
onChange: (value) {
|
onChange: (value) {
|
||||||
context.read<AcBloc>().add(AcBatchControlEvent(
|
context.read<AcBloc>().add(AcBatchControlEvent(
|
||||||
devicesIds: devicesIds,
|
devicesIds: devicesIds,
|
||||||
|
@ -4,11 +4,13 @@ import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
|
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_state.dart';
|
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_state.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/ac_mode.dart';
|
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/ac_mode.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/ac_toggle.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/current_temp.dart';
|
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/current_temp.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/fan_speed.dart';
|
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/fan_speed.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
@ -42,10 +44,21 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
mainAxisSpacing: 12,
|
mainAxisSpacing: 12,
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
AcToggle(
|
ToggleWidget(
|
||||||
|
label: 'Thermostat',
|
||||||
value: state.status.acSwitch,
|
value: state.status.acSwitch,
|
||||||
code: 'switch',
|
code: 'switch',
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
|
icon: Assets.ac,
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<AcBloc>().add(
|
||||||
|
AcControlEvent(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
code: 'switch',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
CurrentTemp(
|
CurrentTemp(
|
||||||
currentTemp: state.status.currentTemp,
|
currentTemp: state.status.currentTemp,
|
||||||
@ -63,13 +76,72 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
code: 'level',
|
code: 'level',
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
),
|
),
|
||||||
AcToggle(
|
ToggleWidget(
|
||||||
value: state.status.childLock,
|
label: '',
|
||||||
code: 'child_lock',
|
labelWidget: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.remove,
|
||||||
|
size: 28,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'06',
|
||||||
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
|
color: ColorsManager.dialogBlueTitle,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'h',
|
||||||
|
style: context.textTheme.bodySmall!
|
||||||
|
.copyWith(color: ColorsManager.blackColor),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'30',
|
||||||
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
|
color: ColorsManager.dialogBlueTitle,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text('m',
|
||||||
|
style: context.textTheme.bodySmall!
|
||||||
|
.copyWith(color: ColorsManager.blackColor)),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: 28,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
value: false,
|
||||||
|
code: 'ac_schedule',
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
description: 'Child Lock',
|
icon: Assets.acSchedule,
|
||||||
icon:
|
onChange: (value) {},
|
||||||
state.status.childLock ? Assets.childLock : Assets.unlock,
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
code: 'child_lock',
|
||||||
|
value: state.status.childLock,
|
||||||
|
label: 'Child Lock',
|
||||||
|
icon: state.status.childLock ? Assets.unlock : Assets.acLock,
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<AcBloc>().add(
|
||||||
|
AcControlEvent(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
code: 'child_lock',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -39,16 +39,21 @@ class AcToggle extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ClipOval(
|
Container(
|
||||||
child: Container(
|
width: 60,
|
||||||
color: ColorsManager.whiteColors,
|
height: 60,
|
||||||
child: SvgPicture.asset(
|
decoration: const BoxDecoration(
|
||||||
icon ?? Assets.lightPulp,
|
shape: BoxShape.circle,
|
||||||
width: 60,
|
color: ColorsManager.whiteColors,
|
||||||
height: 60,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
),
|
||||||
)),
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: ClipOval(
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
icon ?? Assets.lightPulp,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
width: 35,
|
width: 35,
|
||||||
|
@ -12,10 +12,16 @@ import 'package:syncrow_web/pages/device_managment/door_lock/view/door_lock_cont
|
|||||||
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_batch_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart';
|
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart';
|
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart';
|
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_device_control.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_device_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart';
|
||||||
@ -23,6 +29,8 @@ import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_
|
|||||||
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_batch_control.dart';
|
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_batch_control.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_device_control.dart';
|
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_device_control.dart';
|
||||||
|
|
||||||
|
import '../../one_g_glass_switch/view/one_gang_glass_switch_control_view.dart';
|
||||||
|
|
||||||
mixin RouteControlsBasedCode {
|
mixin RouteControlsBasedCode {
|
||||||
Widget routeControlsWidgets({required AllDevicesModel device}) {
|
Widget routeControlsWidgets({required AllDevicesModel device}) {
|
||||||
switch (device.productType) {
|
switch (device.productType) {
|
||||||
@ -38,6 +46,18 @@ mixin RouteControlsBasedCode {
|
|||||||
return LivingRoomDeviceControlsView(
|
return LivingRoomDeviceControlsView(
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
);
|
);
|
||||||
|
case '1GT':
|
||||||
|
return OneGangGlassSwitchControlView(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
);
|
||||||
|
case '2GT':
|
||||||
|
return TwoGangGlassSwitchControlView(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
);
|
||||||
|
case '3GT':
|
||||||
|
return ThreeGangGlassSwitchControlView(
|
||||||
|
deviceId: device.uuid!,
|
||||||
|
);
|
||||||
case 'GW':
|
case 'GW':
|
||||||
return GateWayControlsView(
|
return GateWayControlsView(
|
||||||
gatewayId: device.uuid!,
|
gatewayId: device.uuid!,
|
||||||
@ -76,79 +96,66 @@ mixin RouteControlsBasedCode {
|
|||||||
WPS:
|
WPS:
|
||||||
CPS:
|
CPS:
|
||||||
AC:
|
AC:
|
||||||
CUR:
|
CUR:
|
||||||
|
WH:
|
||||||
|
DS:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Widget routeBatchControlsWidgets({required List<AllDevicesModel> devices}) {
|
Widget routeBatchControlsWidgets({required List<AllDevicesModel> devices}) {
|
||||||
switch (devices.first.productType) {
|
switch (devices.first.productType) {
|
||||||
case '1G':
|
case '1G':
|
||||||
return WallLightBatchControlView(
|
return WallLightBatchControlView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == '1G')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == '1G'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case '2G':
|
case '2G':
|
||||||
return TwoGangBatchControlView(
|
return TwoGangBatchControlView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == '2G')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == '2G'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case '3G':
|
case '3G':
|
||||||
return LivingRoomBatchControlsView(
|
return LivingRoomBatchControlsView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == '3G')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == '3G'))
|
);
|
||||||
.map((e) => e.uuid!)
|
case '1GT':
|
||||||
.toList(),
|
return OneGangGlassSwitchBatchControlView(
|
||||||
|
deviceIds: devices.where((e) => (e.productType == '1GT')).map((e) => e.uuid!).toList(),
|
||||||
|
);
|
||||||
|
case '2GT':
|
||||||
|
return TwoGangGlassSwitchBatchControlView(
|
||||||
|
deviceIds: devices.where((e) => (e.productType == '2GT')).map((e) => e.uuid!).toList(),
|
||||||
|
);
|
||||||
|
case '3GT':
|
||||||
|
return ThreeGangGlassSwitchBatchControlView(
|
||||||
|
deviceIds: devices.where((e) => (e.productType == '3GT')).map((e) => e.uuid!).toList(),
|
||||||
);
|
);
|
||||||
case 'GW':
|
case 'GW':
|
||||||
return GatewayBatchControlView(
|
return GatewayBatchControlView(
|
||||||
gatewayIds: devices
|
gatewayIds: devices.where((e) => (e.productType == 'GW')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'GW'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case 'DL':
|
case 'DL':
|
||||||
return DoorLockBatchControlView(
|
return DoorLockBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'DL')).map((e) => e.uuid!).toList());
|
||||||
.where((e) => (e.productType == 'DL'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList());
|
|
||||||
case 'WPS':
|
case 'WPS':
|
||||||
return WallSensorBatchControlView(
|
return WallSensorBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'WPS')).map((e) => e.uuid!).toList());
|
||||||
.where((e) => (e.productType == 'WPS'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList());
|
|
||||||
case 'CPS':
|
case 'CPS':
|
||||||
return CeilingSensorBatchControlView(
|
return CeilingSensorBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'CPS')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'CPS'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case 'CUR':
|
case 'CUR':
|
||||||
return CurtainBatchStatusView(
|
return CurtainBatchStatusView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'CUR')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'CUR'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
case 'AC':
|
case 'AC':
|
||||||
return AcDeviceBatchControlView(
|
return AcDeviceBatchControlView(
|
||||||
devicesIds: devices
|
devicesIds: devices.where((e) => (e.productType == 'AC')).map((e) => e.uuid!).toList());
|
||||||
.where((e) => (e.productType == 'AC'))
|
|
||||||
.map((e) => e.uuid!)
|
|
||||||
.toList());
|
|
||||||
case 'WH':
|
case 'WH':
|
||||||
return WaterHEaterBatchControlView(
|
return WaterHEaterBatchControlView(
|
||||||
deviceIds: devices
|
deviceIds: devices.where((e) => (e.productType == 'WH')).map((e) => e.uuid!).toList(),
|
||||||
.where((e) => (e.productType == 'WH'))
|
);
|
||||||
.map((e) => e.uuid!)
|
case 'DS':
|
||||||
.toList(),
|
return MainDoorSensorBatchView(
|
||||||
|
devicesIds: devices.where((e) => (e.productType == 'DS')).map((e) => e.uuid!).toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ class AllDevicesModel {
|
|||||||
int? updateTime;
|
int? updateTime;
|
||||||
String? uuid;
|
String? uuid;
|
||||||
int? batteryLevel;
|
int? batteryLevel;
|
||||||
|
String? productName;
|
||||||
|
|
||||||
AllDevicesModel({
|
AllDevicesModel({
|
||||||
this.room,
|
this.room,
|
||||||
@ -90,6 +91,7 @@ class AllDevicesModel {
|
|||||||
this.updateTime,
|
this.updateTime,
|
||||||
this.uuid,
|
this.uuid,
|
||||||
this.batteryLevel,
|
this.batteryLevel,
|
||||||
|
this.productName,
|
||||||
});
|
});
|
||||||
AllDevicesModel.fromJson(Map<String, dynamic> json) {
|
AllDevicesModel.fromJson(Map<String, dynamic> json) {
|
||||||
room = (json['room'] != null && (json['room'] is Map))
|
room = (json['room'] != null && (json['room'] is Map))
|
||||||
@ -121,6 +123,7 @@ class AllDevicesModel {
|
|||||||
updateTime = int.tryParse(json['updateTime']?.toString() ?? '');
|
updateTime = int.tryParse(json['updateTime']?.toString() ?? '');
|
||||||
uuid = json['uuid']?.toString();
|
uuid = json['uuid']?.toString();
|
||||||
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
|
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
|
||||||
|
productName = json['productName']?.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getDefaultIcon(String? productType) {
|
String _getDefaultIcon(String? productType) {
|
||||||
@ -182,6 +185,7 @@ class AllDevicesModel {
|
|||||||
data['updateTime'] = updateTime;
|
data['updateTime'] = updateTime;
|
||||||
data['uuid'] = uuid;
|
data['uuid'] = uuid;
|
||||||
data['battery'] = batteryLevel;
|
data['battery'] = batteryLevel;
|
||||||
|
data['productName'] = productName;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +218,7 @@ class AllDevicesModel {
|
|||||||
other.timeZone == timeZone &&
|
other.timeZone == timeZone &&
|
||||||
other.updateTime == updateTime &&
|
other.updateTime == updateTime &&
|
||||||
other.uuid == uuid &&
|
other.uuid == uuid &&
|
||||||
|
other.productName == productName &&
|
||||||
other.batteryLevel == batteryLevel;
|
other.batteryLevel == batteryLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +248,7 @@ class AllDevicesModel {
|
|||||||
timeZone.hashCode ^
|
timeZone.hashCode ^
|
||||||
updateTime.hashCode ^
|
updateTime.hashCode ^
|
||||||
uuid.hashCode ^
|
uuid.hashCode ^
|
||||||
|
productName.hashCode ^
|
||||||
batteryLevel.hashCode;
|
batteryLevel.hashCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
offlineCount = state.offlineCount;
|
offlineCount = state.offlineCount;
|
||||||
lowBatteryCount = state.lowBatteryCount;
|
lowBatteryCount = state.lowBatteryCount;
|
||||||
isControlButtonEnabled = state.isControlButtonEnabled;
|
isControlButtonEnabled = state.isControlButtonEnabled;
|
||||||
selectedDevices =
|
selectedDevices = state.selectedDevice ??
|
||||||
state.selectedDevice ?? context.read<DeviceManagementBloc>().selectedDevices;
|
context.read<DeviceManagementBloc>().selectedDevices;
|
||||||
} else if (state is DeviceManagementFiltered) {
|
} else if (state is DeviceManagementFiltered) {
|
||||||
devicesToShow = state.filteredDevices;
|
devicesToShow = state.filteredDevices;
|
||||||
selectedIndex = state.selectedIndex;
|
selectedIndex = state.selectedIndex;
|
||||||
@ -46,8 +46,8 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
offlineCount = state.offlineCount;
|
offlineCount = state.offlineCount;
|
||||||
lowBatteryCount = state.lowBatteryCount;
|
lowBatteryCount = state.lowBatteryCount;
|
||||||
isControlButtonEnabled = state.isControlButtonEnabled;
|
isControlButtonEnabled = state.isControlButtonEnabled;
|
||||||
selectedDevices =
|
selectedDevices = state.selectedDevice ??
|
||||||
state.selectedDevice ?? context.read<DeviceManagementBloc>().selectedDevices;
|
context.read<DeviceManagementBloc>().selectedDevices;
|
||||||
} else if (state is DeviceManagementInitial) {
|
} else if (state is DeviceManagementInitial) {
|
||||||
devicesToShow = [];
|
devicesToShow = [];
|
||||||
selectedIndex = 0;
|
selectedIndex = 0;
|
||||||
@ -61,13 +61,15 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
'Low Battery ($lowBatteryCount)',
|
'Low Battery ($lowBatteryCount)',
|
||||||
];
|
];
|
||||||
|
|
||||||
final buttonLabel = (selectedDevices.length > 1) ? 'Batch Control' : 'Control';
|
final buttonLabel =
|
||||||
|
(selectedDevices.length > 1) ? 'Batch Control' : 'Control';
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding:
|
padding: isLargeScreenSize(context)
|
||||||
isLargeScreenSize(context) ? const EdgeInsets.all(30) : const EdgeInsets.all(15),
|
? const EdgeInsets.all(30)
|
||||||
|
: const EdgeInsets.all(15),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -76,7 +78,9 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
tabs: tabs,
|
tabs: tabs,
|
||||||
selectedIndex: selectedIndex,
|
selectedIndex: selectedIndex,
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
context.read<DeviceManagementBloc>().add(SelectedFilterChanged(index));
|
context
|
||||||
|
.read<DeviceManagementBloc>()
|
||||||
|
.add(SelectedFilterChanged(index));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
@ -98,12 +102,14 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (selectedDevices.length > 1) {
|
} else if (selectedDevices.length > 1) {
|
||||||
final productTypes =
|
final productTypes = selectedDevices
|
||||||
selectedDevices.map((device) => device.productType).toSet();
|
.map((device) => device.productType)
|
||||||
|
.toSet();
|
||||||
if (productTypes.length == 1) {
|
if (productTypes.length == 1) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => DeviceBatchControlDialog(
|
builder: (context) =>
|
||||||
|
DeviceBatchControlDialog(
|
||||||
devices: selectedDevices,
|
devices: selectedDevices,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -117,7 +123,9 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: isControlButtonEnabled ? Colors.white : Colors.grey,
|
color: isControlButtonEnabled
|
||||||
|
? Colors.white
|
||||||
|
: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -136,7 +144,9 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
cellDecoration: containerDecoration,
|
cellDecoration: containerDecoration,
|
||||||
onRowSelected: (index, isSelected, row) {
|
onRowSelected: (index, isSelected, row) {
|
||||||
final selectedDevice = devicesToShow[index];
|
final selectedDevice = devicesToShow[index];
|
||||||
context.read<DeviceManagementBloc>().add(SelectDevice(selectedDevice));
|
context
|
||||||
|
.read<DeviceManagementBloc>()
|
||||||
|
.add(SelectDevice(selectedDevice));
|
||||||
},
|
},
|
||||||
withCheckBox: true,
|
withCheckBox: true,
|
||||||
size: context.screenSize,
|
size: context.screenSize,
|
||||||
@ -154,21 +164,25 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
],
|
],
|
||||||
data: devicesToShow.map((device) {
|
data: devicesToShow.map((device) {
|
||||||
return [
|
return [
|
||||||
device.categoryName ?? '',
|
|
||||||
device.name ?? '',
|
device.name ?? '',
|
||||||
|
device.productName ?? '',
|
||||||
device.uuid ?? '',
|
device.uuid ?? '',
|
||||||
device.unit?.name ?? '',
|
device.unit?.name ?? '',
|
||||||
device.room?.name ?? '',
|
device.room?.name ?? '',
|
||||||
device.batteryLevel != null ? '${device.batteryLevel}%' : '-',
|
device.batteryLevel != null
|
||||||
formatDateTime(
|
? '${device.batteryLevel}%'
|
||||||
DateTime.fromMillisecondsSinceEpoch((device.createTime ?? 0) * 1000)),
|
: '-',
|
||||||
|
formatDateTime(DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
(device.createTime ?? 0) * 1000)),
|
||||||
device.online == true ? 'Online' : 'Offline',
|
device.online == true ? 'Online' : 'Offline',
|
||||||
formatDateTime(
|
formatDateTime(DateTime.fromMillisecondsSinceEpoch(
|
||||||
DateTime.fromMillisecondsSinceEpoch((device.updateTime ?? 0) * 1000)),
|
(device.updateTime ?? 0) * 1000)),
|
||||||
];
|
];
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onSelectionChanged: (selectedRows) {
|
onSelectionChanged: (selectedRows) {
|
||||||
context.read<DeviceManagementBloc>().add(UpdateSelection(selectedRows));
|
context
|
||||||
|
.read<DeviceManagementBloc>()
|
||||||
|
.add(UpdateSelection(selectedRows));
|
||||||
},
|
},
|
||||||
initialSelectedIds: context
|
initialSelectedIds: context
|
||||||
.read<DeviceManagementBloc>()
|
.read<DeviceManagementBloc>()
|
||||||
|
@ -73,7 +73,7 @@ class CeilingSensorBatchControlView extends StatelessWidget
|
|||||||
value: model.sensitivity.toDouble(),
|
value: model.sensitivity.toDouble(),
|
||||||
title: 'Sensitivity:',
|
title: 'Sensitivity:',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 10,
|
||||||
steps: 1,
|
steps: 1,
|
||||||
action: (int value) {
|
action: (int value) {
|
||||||
context.read<CeilingSensorBloc>().add(
|
context.read<CeilingSensorBloc>().add(
|
||||||
|
@ -112,7 +112,7 @@ class CeilingSensorControlsView extends StatelessWidget
|
|||||||
value: model.sensitivity.toDouble(),
|
value: model.sensitivity.toDouble(),
|
||||||
title: 'Sensitivity:',
|
title: 'Sensitivity:',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 10,
|
||||||
steps: 1,
|
steps: 1,
|
||||||
action: (int value) {
|
action: (int value) {
|
||||||
context.read<CeilingSensorBloc>().add(
|
context.read<CeilingSensorBloc>().add(
|
||||||
|
@ -15,26 +15,24 @@ class DoorLockBatchControlView extends StatelessWidget
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
return Row(
|
||||||
final isLarge = isLargeScreenSize(context);
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
final isMedium = isMediumScreenSize(context);
|
children: [
|
||||||
return SizedBox(
|
SizedBox(
|
||||||
child: GridView(
|
width: 170,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
|
height: 140,
|
||||||
shrinkWrap: true,
|
child: FirmwareUpdateWidget(
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: isLarge || isExtraLarge || isMedium ? 2 : 1,
|
|
||||||
mainAxisExtent: 140,
|
|
||||||
crossAxisSpacing: 12,
|
|
||||||
mainAxisSpacing: 12,
|
|
||||||
),
|
|
||||||
children: [
|
|
||||||
FirmwareUpdateWidget(
|
|
||||||
deviceId: devicesIds.first,
|
deviceId: devicesIds.first,
|
||||||
version: 12,
|
version: 12,
|
||||||
),
|
),
|
||||||
FactoryResetWidget(
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 170,
|
||||||
|
height: 140,
|
||||||
|
child: FactoryResetWidget(
|
||||||
callFactoryReset: () {
|
callFactoryReset: () {
|
||||||
BlocProvider.of<DoorLockBloc>(context).add(
|
BlocProvider.of<DoorLockBloc>(context).add(
|
||||||
DoorLockFactoryReset(
|
DoorLockFactoryReset(
|
||||||
@ -44,8 +42,8 @@ class DoorLockBatchControlView extends StatelessWidget
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,6 @@ class GatewayBatchControlView extends StatelessWidget
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
|
||||||
final isLarge = isLargeScreenSize(context);
|
|
||||||
final isMedium = isMediumScreenSize(context);
|
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => GateWayBloc()..add(GatWayById(gatewayIds.first)),
|
create: (context) => GateWayBloc()..add(GatWayById(gatewayIds.first)),
|
||||||
child: BlocBuilder<GateWayBloc, GateWayState>(
|
child: BlocBuilder<GateWayBloc, GateWayState>(
|
||||||
@ -25,28 +21,31 @@ class GatewayBatchControlView extends StatelessWidget
|
|||||||
if (state is GatewayLoadingState) {
|
if (state is GatewayLoadingState) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
} else if (state is UpdateGatewayState) {
|
} else if (state is UpdateGatewayState) {
|
||||||
return GridView(
|
return Row(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
shrinkWrap: true,
|
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: isLarge || isExtraLarge || isMedium ? 2 : 1,
|
|
||||||
mainAxisExtent: 140,
|
|
||||||
crossAxisSpacing: 12,
|
|
||||||
mainAxisSpacing: 12,
|
|
||||||
),
|
|
||||||
children: [
|
children: [
|
||||||
FirmwareUpdateWidget(deviceId: gatewayIds.first, version: 2),
|
SizedBox(
|
||||||
FactoryResetWidget(
|
width: 170,
|
||||||
callFactoryReset: () {
|
height: 140,
|
||||||
context.read<GateWayBloc>().add(
|
child: FirmwareUpdateWidget(
|
||||||
GateWayFactoryReset(
|
deviceId: gatewayIds.first, version: 2)),
|
||||||
deviceId: gatewayIds.first,
|
const SizedBox(
|
||||||
factoryReset:
|
width: 12,
|
||||||
FactoryResetModel(devicesUuid: gatewayIds),
|
),
|
||||||
),
|
SizedBox(
|
||||||
);
|
width: 170,
|
||||||
},
|
height: 140,
|
||||||
|
child: FactoryResetWidget(
|
||||||
|
callFactoryReset: () {
|
||||||
|
context.read<GateWayBloc>().add(
|
||||||
|
GateWayFactoryReset(
|
||||||
|
deviceId: gatewayIds.first,
|
||||||
|
factoryReset:
|
||||||
|
FactoryResetModel(devicesUuid: gatewayIds),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -67,22 +67,19 @@ class _DeviceItem extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
ClipOval(
|
||||||
width: 60,
|
child: Container(
|
||||||
height: 60,
|
height: 60,
|
||||||
decoration: const BoxDecoration(
|
width: 60,
|
||||||
shape: BoxShape.circle,
|
padding: const EdgeInsets.all(8),
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.whiteColors,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
device.icon,
|
||||||
|
width: 35,
|
||||||
|
height: 35,
|
||||||
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
)),
|
||||||
padding: const EdgeInsets.all(4),
|
|
||||||
child: ClipOval(
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
device.icon,
|
|
||||||
fit: BoxFit.fill,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Text(
|
Text(
|
||||||
device.name ?? 'Unknown Device',
|
device.name ?? 'Unknown Device',
|
||||||
|
@ -15,6 +15,7 @@ class MainDoorSensorBloc
|
|||||||
on<MainDoorSensorControl>(_onControl);
|
on<MainDoorSensorControl>(_onControl);
|
||||||
on<MainDoorSensorFetchBatchEvent>(_onFetchBatchStatus);
|
on<MainDoorSensorFetchBatchEvent>(_onFetchBatchStatus);
|
||||||
on<MainDoorSensorReportsEvent>(_fetchReports);
|
on<MainDoorSensorReportsEvent>(_fetchReports);
|
||||||
|
on<MainDoorSensorFactoryReset>(_factoryReset);
|
||||||
}
|
}
|
||||||
|
|
||||||
late MainDoorSensorStatusModel deviceStatus;
|
late MainDoorSensorStatusModel deviceStatus;
|
||||||
@ -137,4 +138,22 @@ class MainDoorSensorBloc
|
|||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _factoryReset(MainDoorSensorFactoryReset event,
|
||||||
|
Emitter<MainDoorSensorState> emit) async {
|
||||||
|
emit(MainDoorSensorLoadingState());
|
||||||
|
try {
|
||||||
|
final response = await DevicesManagementApi().factoryReset(
|
||||||
|
event.factoryReset,
|
||||||
|
event.deviceId,
|
||||||
|
);
|
||||||
|
if (!response) {
|
||||||
|
emit(MainDoorSensorFailedState(error: 'Failed'));
|
||||||
|
} else {
|
||||||
|
add(MainDoorSensorFetchDeviceEvent(event.deviceId));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(MainDoorSensorFailedState(error: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
import '../../all_devices/models/factory_reset_model.dart';
|
||||||
|
|
||||||
class MainDoorSensorEvent extends Equatable {
|
class MainDoorSensorEvent extends Equatable {
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [];
|
List<Object?> get props => [];
|
||||||
@ -61,3 +63,11 @@ class MainDoorSensorReportsEvent extends MainDoorSensorEvent {
|
|||||||
required this.from,
|
required this.from,
|
||||||
required this.to});
|
required this.to});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MainDoorSensorFactoryReset extends MainDoorSensorEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final FactoryResetModel factoryReset;
|
||||||
|
|
||||||
|
MainDoorSensorFactoryReset(
|
||||||
|
{required this.deviceId, required this.factoryReset});
|
||||||
|
}
|
||||||
|
@ -80,7 +80,9 @@ class MainDoorSensorControlView extends StatelessWidget
|
|||||||
icon: Assets.openCloseDoor,
|
icon: Assets.openCloseDoor,
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
status: status.doorContactState,
|
status: status.doorContactState,
|
||||||
textColor: ColorsManager.red,
|
textColor: status.doorContactState
|
||||||
|
? ColorsManager.red
|
||||||
|
: ColorsManager.blackColor,
|
||||||
paddingAmount: 8,
|
paddingAmount: 8,
|
||||||
),
|
),
|
||||||
IconNameStatusContainer(
|
IconNameStatusContainer(
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||||
|
|
||||||
|
class MainDoorSensorBatchView extends StatelessWidget {
|
||||||
|
const MainDoorSensorBatchView({super.key, required this.devicesIds});
|
||||||
|
|
||||||
|
final List<String> devicesIds;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 170,
|
||||||
|
height: 140,
|
||||||
|
child: FirmwareUpdateWidget(
|
||||||
|
deviceId: devicesIds.first,
|
||||||
|
version: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 170,
|
||||||
|
height: 140,
|
||||||
|
child: FactoryResetWidget(
|
||||||
|
callFactoryReset: () {
|
||||||
|
BlocProvider.of<MainDoorSensorBloc>(context).add(
|
||||||
|
MainDoorSensorFactoryReset(
|
||||||
|
deviceId: devicesIds.first,
|
||||||
|
factoryReset: FactoryResetModel(devicesUuid: devicesIds),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
|
part 'one_gang_glass_switch_event.dart';
|
||||||
|
part 'one_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
|
||||||
|
OneGangGlassStatusModel deviceStatus;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBloc({required String deviceId})
|
||||||
|
: deviceStatus = OneGangGlassStatusModel(uuid: deviceId, switch1: false, countDown: 0),
|
||||||
|
super(OneGangGlassSwitchInitial()) {
|
||||||
|
on<OneGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
||||||
|
on<OneGangGlassSwitchControl>(_onControl);
|
||||||
|
on<OneGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
|
on<OneGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchDeviceStatus(
|
||||||
|
OneGangGlassSwitchFetchDeviceEvent event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
emit(OneGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(OneGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onControl(OneGangGlassSwitchControl event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceId,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(OneGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceIds,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchBatchStatus(
|
||||||
|
OneGangGlassSwitchFetchBatchStatusEvent event, Emitter<OneGangGlassSwitchState> emit) async {
|
||||||
|
emit(OneGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
||||||
|
emit(OneGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(OneGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _runDebounce({
|
||||||
|
required dynamic deviceId,
|
||||||
|
required String code,
|
||||||
|
required bool value,
|
||||||
|
required bool oldValue,
|
||||||
|
required Emitter<OneGangGlassSwitchState> emit,
|
||||||
|
required bool isBatch,
|
||||||
|
}) async {
|
||||||
|
late String id;
|
||||||
|
if (deviceId is List) {
|
||||||
|
id = deviceId.first;
|
||||||
|
} else {
|
||||||
|
id = deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_timer != null) {
|
||||||
|
_timer!.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
|
try {
|
||||||
|
late bool response;
|
||||||
|
if (isBatch) {
|
||||||
|
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
||||||
|
} else {
|
||||||
|
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<OneGangGlassSwitchState> emit) {
|
||||||
|
_updateLocalValue(code, oldValue);
|
||||||
|
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateLocalValue(String code, bool value) {
|
||||||
|
if (code == 'switch_1') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch1: value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _getValueByCode(String code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'switch_1':
|
||||||
|
return deviceStatus.switch1;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
_timer?.cancel();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
part of 'one_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class OneGangGlassSwitchEvent {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchFetchDeviceEvent extends OneGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
OneGangGlassSwitchFetchDeviceEvent(this.deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchControl extends OneGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
OneGangGlassSwitchControl({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchControl extends OneGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBatchControl({
|
||||||
|
required this.deviceIds,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchFetchBatchStatusEvent extends OneGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
OneGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
part of 'one_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class OneGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchInitial extends OneGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchLoading extends OneGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchStatusLoaded extends OneGangGlassSwitchState {
|
||||||
|
final OneGangGlassStatusModel status;
|
||||||
|
|
||||||
|
OneGangGlassSwitchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchError extends OneGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
OneGangGlassSwitchError(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchStatusLoaded extends OneGangGlassSwitchState {
|
||||||
|
final OneGangGlassStatusModel status;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBatchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchControlError extends OneGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
OneGangGlassSwitchBatchControlError(this.message);
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
|
||||||
|
class OneGangGlassStatusModel {
|
||||||
|
final String uuid;
|
||||||
|
final bool switch1;
|
||||||
|
final int countDown;
|
||||||
|
|
||||||
|
OneGangGlassStatusModel({
|
||||||
|
required this.uuid,
|
||||||
|
required this.switch1,
|
||||||
|
required this.countDown,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory OneGangGlassStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||||
|
late bool switch1;
|
||||||
|
late int countDown;
|
||||||
|
|
||||||
|
for (var status in jsonList) {
|
||||||
|
switch (status.code) {
|
||||||
|
case 'switch_1':
|
||||||
|
switch1 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_1':
|
||||||
|
countDown = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OneGangGlassStatusModel(
|
||||||
|
uuid: id,
|
||||||
|
switch1: switch1,
|
||||||
|
countDown: countDown,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
OneGangGlassStatusModel copyWith({
|
||||||
|
String? uuid,
|
||||||
|
bool? switch1,
|
||||||
|
int? countDown,
|
||||||
|
}) {
|
||||||
|
return OneGangGlassStatusModel(
|
||||||
|
uuid: uuid ?? this.uuid,
|
||||||
|
switch1: switch1 ?? this.switch1,
|
||||||
|
countDown: countDown ?? this.countDown,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'OneGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown: $countDown)';
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class OneGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
const OneGangGlassSwitchBatchControlView({required this.deviceIds, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
OneGangGlassSwitchBloc(deviceId: deviceIds.first)..add(OneGangGlassSwitchFetchBatchStatusEvent(deviceIds)),
|
||||||
|
child: BlocBuilder<OneGangGlassSwitchBloc, OneGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is OneGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is OneGangGlassSwitchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is OneGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Wall Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<OneGangGlassSwitchBloc>().add(
|
||||||
|
OneGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FirmwareUpdateWidget(
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
version: 12, // adjust the version according to your requirement
|
||||||
|
),
|
||||||
|
FactoryResetWidget(
|
||||||
|
callFactoryReset: () {},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
const OneGangGlassSwitchControlView({required this.deviceId, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
OneGangGlassSwitchBloc(deviceId: deviceId)..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)),
|
||||||
|
child: BlocBuilder<OneGangGlassSwitchBloc, OneGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is OneGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is OneGangGlassSwitchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is OneGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Wall Lightً',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<OneGangGlassSwitchBloc>().add(
|
||||||
|
OneGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: false,
|
||||||
|
code: '',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Preferences',
|
||||||
|
icon: Assets.preferences,
|
||||||
|
onChange: (value) {},
|
||||||
|
showToggle: false,
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: false,
|
||||||
|
code: '',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Scheduling',
|
||||||
|
icon: Assets.scheduling,
|
||||||
|
onChange: (value) {},
|
||||||
|
showToggle: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,47 +1,119 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
class FactoryResetWidget extends StatelessWidget {
|
class FactoryResetWidget extends StatefulWidget {
|
||||||
const FactoryResetWidget({super.key, required this.callFactoryReset});
|
const FactoryResetWidget({super.key, required this.callFactoryReset});
|
||||||
|
|
||||||
final Null Function() callFactoryReset;
|
final Function() callFactoryReset;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FactoryResetWidget> createState() => _FactoryResetWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FactoryResetWidgetState extends State<FactoryResetWidget> {
|
||||||
|
bool _showConfirmation = false;
|
||||||
|
|
||||||
|
void _toggleConfirmation() {
|
||||||
|
setState(() {
|
||||||
|
_showConfirmation = !_showConfirmation;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DeviceControlsContainer(
|
return DeviceControlsContainer(
|
||||||
child: GestureDetector(
|
child: _showConfirmation
|
||||||
onTap: callFactoryReset,
|
? Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
children: [
|
||||||
children: [
|
Text(
|
||||||
ClipOval(
|
'Factory Reset',
|
||||||
child: Container(
|
style: context.textTheme.titleMedium!.copyWith(
|
||||||
color: ColorsManager.whiteColors,
|
fontWeight: FontWeight.bold,
|
||||||
height: 60,
|
color: ColorsManager.blackColor,
|
||||||
width: 60,
|
),
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(12.0),
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.factoryReset,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
)),
|
'Are you sure?',
|
||||||
Text(
|
style: context.textTheme.bodySmall!.copyWith(
|
||||||
'Factory Reset',
|
color: ColorsManager.grayColor,
|
||||||
style: context.textTheme.titleMedium!.copyWith(
|
),
|
||||||
fontWeight: FontWeight.w400,
|
),
|
||||||
color: ColorsManager.blackColor,
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: DefaultButton(
|
||||||
|
height: 20,
|
||||||
|
elevation: 0,
|
||||||
|
onPressed: _toggleConfirmation,
|
||||||
|
backgroundColor: ColorsManager.greyColor,
|
||||||
|
child: Text(
|
||||||
|
'Cancel',
|
||||||
|
style: context.textTheme.bodyMedium!.copyWith(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Flexible(
|
||||||
|
child: DefaultButton(
|
||||||
|
height: 20,
|
||||||
|
elevation: 0,
|
||||||
|
onPressed: widget.callFactoryReset,
|
||||||
|
backgroundColor: ColorsManager.red,
|
||||||
|
child: Text(
|
||||||
|
'Reset',
|
||||||
|
style: context.textTheme.bodyMedium!.copyWith(
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: GestureDetector(
|
||||||
|
onTap: _toggleConfirmation,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
ClipOval(
|
||||||
|
child: Container(
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
height: 60,
|
||||||
|
width: 60,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.factoryReset,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Factory Reset',
|
||||||
|
style: context.textTheme.titleMedium!.copyWith(
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ class DeviceBatchControlDialog extends StatelessWidget
|
|||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
devices.first.categoryName ?? 'Device Control',
|
getBatchDialogName(devices.first),
|
||||||
style: context.textTheme.titleLarge!.copyWith(
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
color: ColorsManager.dialogBlueTitle,
|
color: ColorsManager.dialogBlueTitle,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@ -65,7 +65,7 @@ class DeviceBatchControlDialog extends StatelessWidget
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
padding: EdgeInsets.all(1),
|
padding: const EdgeInsets.all(1),
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.close,
|
Icons.close,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
@ -92,3 +92,42 @@ class DeviceBatchControlDialog extends StatelessWidget
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getBatchDialogName(AllDevicesModel device) {
|
||||||
|
/*
|
||||||
|
3G:
|
||||||
|
1G:
|
||||||
|
2G:
|
||||||
|
GW:
|
||||||
|
DL:
|
||||||
|
WPS:
|
||||||
|
CPS:
|
||||||
|
AC:
|
||||||
|
CUR:
|
||||||
|
WH:
|
||||||
|
*/
|
||||||
|
switch (device.productType) {
|
||||||
|
case '1G':
|
||||||
|
return "Smart Light Switch";
|
||||||
|
case '2G':
|
||||||
|
return "2Gang Light";
|
||||||
|
case '3G':
|
||||||
|
return "Living Room";
|
||||||
|
case 'GW':
|
||||||
|
return "GateWay";
|
||||||
|
case 'DL':
|
||||||
|
return "Door Lock";
|
||||||
|
case 'WPS':
|
||||||
|
return "White Presence Sensor";
|
||||||
|
case 'CPS':
|
||||||
|
return "Black Presence Sensor";
|
||||||
|
case 'CUR':
|
||||||
|
return "Smart Curtains";
|
||||||
|
case 'WH':
|
||||||
|
return "Smart Water Hater";
|
||||||
|
case 'AC':
|
||||||
|
return "Smart AC";
|
||||||
|
default:
|
||||||
|
return device.categoryName ?? 'Device Control';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/helper/route_cont
|
|||||||
|
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/format_date_time.dart';
|
||||||
|
|
||||||
class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
|
class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
|
||||||
final AllDevicesModel device;
|
final AllDevicesModel device;
|
||||||
@ -86,13 +87,12 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
|
|||||||
children: [
|
children: [
|
||||||
TableRow(
|
TableRow(
|
||||||
children: [
|
children: [
|
||||||
_buildInfoRow('Product Name:', device.categoryName ?? 'N/A'),
|
_buildInfoRow('Product Name:', device.productName ?? 'N/A'),
|
||||||
_buildInfoRow('Device ID:', device.uuid ?? ''),
|
_buildInfoRow('Device ID:', device.uuid ?? ''),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
TableRow(children: [
|
TableRow(children: [
|
||||||
_buildInfoRow('Virtual Address:',
|
_buildInfoRow('Virtual Address:', device.ip ?? '-'),
|
||||||
'Area - Street 1 - Building 1 - First Floor'),
|
|
||||||
const SizedBox.shrink(),
|
const SizedBox.shrink(),
|
||||||
]),
|
]),
|
||||||
TableRow(
|
TableRow(
|
||||||
@ -103,14 +103,38 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
|
|||||||
),
|
),
|
||||||
TableRow(
|
TableRow(
|
||||||
children: [
|
children: [
|
||||||
_buildInfoRow('Installation Date and Time:', '09/08/2024 13:30'),
|
_buildInfoRow(
|
||||||
const SizedBox.shrink(),
|
'Installation Date and Time:',
|
||||||
|
formatDateTime(
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
((device.createTime ?? 0) * 1000),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_buildInfoRow(
|
||||||
|
'Battery Level:',
|
||||||
|
device.batteryLevel != null
|
||||||
|
? '${device.batteryLevel ?? 0}%'
|
||||||
|
: "-",
|
||||||
|
statusColor: device.batteryLevel != null
|
||||||
|
? (device.batteryLevel! < 20
|
||||||
|
? ColorsManager.red
|
||||||
|
: ColorsManager.green)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
TableRow(
|
TableRow(
|
||||||
children: [
|
children: [
|
||||||
_buildInfoRow('Status:', 'Online', statusColor: Colors.green),
|
_buildInfoRow('Status:', 'Online', statusColor: Colors.green),
|
||||||
_buildInfoRow('Last Offline Date and Time:', '-'),
|
_buildInfoRow(
|
||||||
|
'Last Offline Date and Time:',
|
||||||
|
formatDateTime(
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
((device.updateTime ?? 0) * 1000),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
@ -11,7 +10,9 @@ class ToggleWidget extends StatelessWidget {
|
|||||||
final String deviceId;
|
final String deviceId;
|
||||||
final String label;
|
final String label;
|
||||||
final String? icon;
|
final String? icon;
|
||||||
|
final Widget? labelWidget;
|
||||||
final Function(dynamic value) onChange;
|
final Function(dynamic value) onChange;
|
||||||
|
final bool showToggle;
|
||||||
|
|
||||||
const ToggleWidget({
|
const ToggleWidget({
|
||||||
super.key,
|
super.key,
|
||||||
@ -21,6 +22,8 @@ class ToggleWidget extends StatelessWidget {
|
|||||||
required this.label,
|
required this.label,
|
||||||
required this.onChange,
|
required this.onChange,
|
||||||
this.icon,
|
this.icon,
|
||||||
|
this.labelWidget,
|
||||||
|
this.showToggle = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -32,32 +35,49 @@ class ToggleWidget extends StatelessWidget {
|
|||||||
border: Border.all(color: ColorsManager.boxDivider),
|
border: Border.all(color: ColorsManager.boxDivider),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Row(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Padding(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
padding: const EdgeInsets.only(right: 12),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Row(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
icon == '-1'
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
? const SizedBox(
|
children: [
|
||||||
height: 60,
|
icon == '-1'
|
||||||
width: 60,
|
? const SizedBox(
|
||||||
)
|
height: 60,
|
||||||
: ClipOval(
|
width: 60,
|
||||||
child: Container(
|
)
|
||||||
height: 60,
|
: ClipOval(
|
||||||
width: 60,
|
child: Container(
|
||||||
padding: const EdgeInsets.all(8),
|
height: 60,
|
||||||
color: ColorsManager.whiteColors,
|
width: 60,
|
||||||
child: SvgPicture.asset(
|
padding: const EdgeInsets.all(8),
|
||||||
icon ?? Assets.lightPulp,
|
color: ColorsManager.whiteColors,
|
||||||
width: 35,
|
child: SvgPicture.asset(
|
||||||
height: 35,
|
icon ?? Assets.lightPulp,
|
||||||
fit: BoxFit.contain,
|
width: 35,
|
||||||
),
|
height: 35,
|
||||||
)),
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
if (showToggle)
|
||||||
|
Container(
|
||||||
|
height: 20,
|
||||||
|
width: 35,
|
||||||
|
padding: const EdgeInsets.only(right: 16, top: 10),
|
||||||
|
child: CupertinoSwitch(
|
||||||
|
value: value,
|
||||||
|
activeColor: ColorsManager.dialogBlueTitle,
|
||||||
|
onChanged: onChange,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
labelWidget ??
|
||||||
Text(
|
Text(
|
||||||
label,
|
label,
|
||||||
style: context.textTheme.titleMedium!.copyWith(
|
style: context.textTheme.titleMedium!.copyWith(
|
||||||
@ -65,18 +85,6 @@ class ToggleWidget extends StatelessWidget {
|
|||||||
color: ColorsManager.blackColor,
|
color: ColorsManager.blackColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: 20,
|
|
||||||
width: 35,
|
|
||||||
padding: const EdgeInsets.only(right: 16, top: 10),
|
|
||||||
child: CupertinoSwitch(
|
|
||||||
value: value,
|
|
||||||
activeColor: ColorsManager.dialogBlueTitle,
|
|
||||||
onChanged: onChange,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,174 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart';
|
||||||
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
|
part 'three_gang_glass_switch_event.dart';
|
||||||
|
part 'three_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchBloc extends Bloc<ThreeGangGlassSwitchEvent, ThreeGangGlassSwitchState> {
|
||||||
|
ThreeGangGlassStatusModel deviceStatus;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchBloc({required String deviceId})
|
||||||
|
: deviceStatus = ThreeGangGlassStatusModel(
|
||||||
|
uuid: deviceId,
|
||||||
|
switch1: false,
|
||||||
|
countDown1: 0,
|
||||||
|
switch2: false,
|
||||||
|
countDown2: 0,
|
||||||
|
switch3: false,
|
||||||
|
countDown3: 0),
|
||||||
|
super(ThreeGangGlassSwitchInitial()) {
|
||||||
|
on<ThreeGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
||||||
|
on<ThreeGangGlassSwitchControl>(_onControl);
|
||||||
|
on<ThreeGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
|
on<ThreeGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
|
on<ThreeGangGlassFactoryReset>(_onFactoryReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchDeviceStatus(
|
||||||
|
ThreeGangGlassSwitchFetchDeviceEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
|
emit(ThreeGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onControl(ThreeGangGlassSwitchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceId,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onBatchControl(ThreeGangGlassSwitchBatchControl event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceIds,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchBatchStatus(
|
||||||
|
ThreeGangGlassSwitchFetchBatchStatusEvent event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
|
emit(ThreeGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
||||||
|
emit(ThreeGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFactoryReset(ThreeGangGlassFactoryReset event, Emitter<ThreeGangGlassSwitchState> emit) async {
|
||||||
|
emit(ThreeGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
||||||
|
if (!response) {
|
||||||
|
emit(ThreeGangGlassSwitchError('Failed'));
|
||||||
|
} else {
|
||||||
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(ThreeGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _runDebounce({
|
||||||
|
required dynamic deviceId,
|
||||||
|
required String code,
|
||||||
|
required bool value,
|
||||||
|
required bool oldValue,
|
||||||
|
required Emitter<ThreeGangGlassSwitchState> emit,
|
||||||
|
required bool isBatch,
|
||||||
|
}) async {
|
||||||
|
late String id;
|
||||||
|
if (deviceId is List) {
|
||||||
|
id = deviceId.first;
|
||||||
|
} else {
|
||||||
|
id = deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_timer != null) {
|
||||||
|
_timer!.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
|
try {
|
||||||
|
late bool response;
|
||||||
|
if (isBatch) {
|
||||||
|
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
||||||
|
} else {
|
||||||
|
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<ThreeGangGlassSwitchState> emit) {
|
||||||
|
_updateLocalValue(code, oldValue);
|
||||||
|
emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateLocalValue(String code, bool value) {
|
||||||
|
if (code == 'switch_1') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch1: value);
|
||||||
|
} else if (code == 'switch_2') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch2: value);
|
||||||
|
} else if (code == 'switch_3') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch3: value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _getValueByCode(String code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'switch_1':
|
||||||
|
return deviceStatus.switch1;
|
||||||
|
case 'switch_2':
|
||||||
|
return deviceStatus.switch2;
|
||||||
|
case 'switch_3':
|
||||||
|
return deviceStatus.switch3;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
_timer?.cancel();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
part of 'three_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class ThreeGangGlassSwitchEvent {}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchFetchDeviceEvent extends ThreeGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchFetchDeviceEvent(this.deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchControl extends ThreeGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchControl({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchBatchControl extends ThreeGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchBatchControl({
|
||||||
|
required this.deviceIds,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchFetchBatchStatusEvent extends ThreeGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeGangGlassFactoryReset extends ThreeGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final FactoryResetModel factoryReset;
|
||||||
|
|
||||||
|
ThreeGangGlassFactoryReset({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.factoryReset,
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
part of 'three_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class ThreeGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchInitial extends ThreeGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchLoading extends ThreeGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchStatusLoaded extends ThreeGangGlassSwitchState {
|
||||||
|
final ThreeGangGlassStatusModel status;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchError extends ThreeGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchError(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchBatchStatusLoaded extends ThreeGangGlassSwitchState {
|
||||||
|
final ThreeGangGlassStatusModel status;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchBatchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchBatchControlError extends ThreeGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
ThreeGangGlassSwitchBatchControlError(this.message);
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
|
||||||
|
class ThreeGangGlassStatusModel {
|
||||||
|
final String uuid;
|
||||||
|
final bool switch1;
|
||||||
|
final int countDown1;
|
||||||
|
final bool switch2;
|
||||||
|
final int countDown2;
|
||||||
|
final bool switch3;
|
||||||
|
final int countDown3;
|
||||||
|
|
||||||
|
ThreeGangGlassStatusModel({
|
||||||
|
required this.uuid,
|
||||||
|
required this.switch1,
|
||||||
|
required this.countDown1,
|
||||||
|
required this.switch2,
|
||||||
|
required this.countDown2,
|
||||||
|
required this.switch3,
|
||||||
|
required this.countDown3,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ThreeGangGlassStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||||
|
late bool switch1;
|
||||||
|
late int countDown1;
|
||||||
|
late bool switch2;
|
||||||
|
late int countDown2;
|
||||||
|
late bool switch3;
|
||||||
|
late int countDown3;
|
||||||
|
|
||||||
|
for (var status in jsonList) {
|
||||||
|
switch (status.code) {
|
||||||
|
case 'switch_1':
|
||||||
|
switch1 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_1':
|
||||||
|
countDown1 = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
case 'switch_2':
|
||||||
|
switch2 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_2':
|
||||||
|
countDown2 = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
case 'switch_3':
|
||||||
|
switch3 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_3':
|
||||||
|
countDown3 = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ThreeGangGlassStatusModel(
|
||||||
|
uuid: id,
|
||||||
|
switch1: switch1,
|
||||||
|
countDown1: countDown1,
|
||||||
|
switch2: switch2,
|
||||||
|
countDown2: countDown2,
|
||||||
|
switch3: switch3,
|
||||||
|
countDown3: countDown3,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreeGangGlassStatusModel copyWith({
|
||||||
|
String? uuid,
|
||||||
|
bool? switch1,
|
||||||
|
int? countDown1,
|
||||||
|
bool? switch2,
|
||||||
|
int? countDown2,
|
||||||
|
bool? switch3,
|
||||||
|
int? countDown3,
|
||||||
|
}) {
|
||||||
|
return ThreeGangGlassStatusModel(
|
||||||
|
uuid: uuid ?? this.uuid,
|
||||||
|
switch1: switch1 ?? this.switch1,
|
||||||
|
countDown1: countDown1 ?? this.countDown1,
|
||||||
|
switch2: switch2 ?? this.switch2,
|
||||||
|
countDown2: countDown2 ?? this.countDown2,
|
||||||
|
switch3: switch3 ?? this.switch3,
|
||||||
|
countDown3: countDown3 ?? this.countDown3,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'ThreeGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown1: $countDown1, switch2: $switch2, countDown2: $countDown2, switch3: $switch3, countDown3: $countDown3)';
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
const ThreeGangGlassSwitchBatchControlView({required this.deviceIds, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) => ThreeGangGlassSwitchBloc(deviceId: deviceIds.first)
|
||||||
|
..add(ThreeGangGlassSwitchFetchBatchStatusEvent(deviceIds)),
|
||||||
|
child: BlocBuilder<ThreeGangGlassSwitchBloc, ThreeGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is ThreeGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is ThreeGangGlassSwitchBatchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is ThreeGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Glass Switch 1',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||||
|
ThreeGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch2,
|
||||||
|
code: 'switch_2',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Glass Switch 2',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||||
|
ThreeGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch3,
|
||||||
|
code: 'switch_3',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Glass Switch 3',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||||
|
ThreeGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_3',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FirmwareUpdateWidget(
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
version: 12, // adjust the version according to your requirement
|
||||||
|
),
|
||||||
|
FactoryResetWidget(
|
||||||
|
callFactoryReset: () {
|
||||||
|
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||||
|
ThreeGangGlassFactoryReset(
|
||||||
|
deviceId: status.uuid,
|
||||||
|
factoryReset: FactoryResetModel(devicesUuid: deviceIds),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
import '../models/three_gang_glass_switch.dart';
|
||||||
|
|
||||||
|
class ThreeGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
const ThreeGangGlassSwitchControlView({required this.deviceId, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
ThreeGangGlassSwitchBloc(deviceId: deviceId)..add(ThreeGangGlassSwitchFetchDeviceEvent(deviceId)),
|
||||||
|
child: BlocBuilder<ThreeGangGlassSwitchBloc, ThreeGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is ThreeGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is ThreeGangGlassSwitchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is ThreeGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, ThreeGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Wall Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||||
|
ThreeGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch2,
|
||||||
|
code: 'switch_2',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Ceiling Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||||
|
ThreeGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch3,
|
||||||
|
code: 'switch_3',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'SpotLight',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<ThreeGangGlassSwitchBloc>().add(
|
||||||
|
ThreeGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_3',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: false,
|
||||||
|
code: '',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Preferences',
|
||||||
|
icon: Assets.preferences,
|
||||||
|
onChange: (value) {},
|
||||||
|
showToggle: false,
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: false,
|
||||||
|
code: '',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Scheduling',
|
||||||
|
icon: Assets.scheduling,
|
||||||
|
onChange: (value) {},
|
||||||
|
showToggle: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
|
part 'two_gang_glass_switch_event.dart';
|
||||||
|
part 'two_gang_glass_switch_state.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBloc extends Bloc<TwoGangGlassSwitchEvent, TwoGangGlassSwitchState> {
|
||||||
|
TwoGangGlassStatusModel deviceStatus;
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBloc({required String deviceId})
|
||||||
|
: deviceStatus =
|
||||||
|
TwoGangGlassStatusModel(uuid: deviceId, switch1: false, countDown1: 0, switch2: false, countDown2: 0),
|
||||||
|
super(TwoGangGlassSwitchInitial()) {
|
||||||
|
on<TwoGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
|
||||||
|
on<TwoGangGlassSwitchControl>(_onControl);
|
||||||
|
on<TwoGangGlassSwitchBatchControl>(_onBatchControl);
|
||||||
|
on<TwoGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
|
||||||
|
on<TwoGangGlassFactoryReset>(_onFactoryReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchDeviceStatus(
|
||||||
|
TwoGangGlassSwitchFetchDeviceEvent event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
emit(TwoGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
|
deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceId, status.status);
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(TwoGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onControl(TwoGangGlassSwitchControl event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceId,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onBatchControl(TwoGangGlassSwitchBatchControl event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
|
_updateLocalValue(event.code, event.value);
|
||||||
|
emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
|
await _runDebounce(
|
||||||
|
deviceId: event.deviceIds,
|
||||||
|
code: event.code,
|
||||||
|
value: event.value,
|
||||||
|
oldValue: oldValue,
|
||||||
|
emit: emit,
|
||||||
|
isBatch: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFetchBatchStatus(
|
||||||
|
TwoGangGlassSwitchFetchBatchStatusEvent event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
emit(TwoGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||||
|
deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
|
||||||
|
emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus));
|
||||||
|
} catch (e) {
|
||||||
|
emit(TwoGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onFactoryReset(TwoGangGlassFactoryReset event, Emitter<TwoGangGlassSwitchState> emit) async {
|
||||||
|
emit(TwoGangGlassSwitchLoading());
|
||||||
|
try {
|
||||||
|
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
|
||||||
|
if (!response) {
|
||||||
|
emit(TwoGangGlassSwitchError('Failed'));
|
||||||
|
} else {
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(TwoGangGlassSwitchError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _runDebounce({
|
||||||
|
required dynamic deviceId,
|
||||||
|
required String code,
|
||||||
|
required bool value,
|
||||||
|
required bool oldValue,
|
||||||
|
required Emitter<TwoGangGlassSwitchState> emit,
|
||||||
|
required bool isBatch,
|
||||||
|
}) async {
|
||||||
|
late String id;
|
||||||
|
if (deviceId is List) {
|
||||||
|
id = deviceId.first;
|
||||||
|
} else {
|
||||||
|
id = deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_timer != null) {
|
||||||
|
_timer!.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
|
try {
|
||||||
|
late bool response;
|
||||||
|
if (isBatch) {
|
||||||
|
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
|
||||||
|
} else {
|
||||||
|
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_revertValueAndEmit(id, code, oldValue, emit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<TwoGangGlassSwitchState> emit) {
|
||||||
|
_updateLocalValue(code, oldValue);
|
||||||
|
emit(TwoGangGlassSwitchStatusLoaded(deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateLocalValue(String code, bool value) {
|
||||||
|
if (code == 'switch_1') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch1: value);
|
||||||
|
} else if (code == 'switch_2') {
|
||||||
|
deviceStatus = deviceStatus.copyWith(switch2: value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _getValueByCode(String code) {
|
||||||
|
switch (code) {
|
||||||
|
case 'switch_1':
|
||||||
|
return deviceStatus.switch1;
|
||||||
|
case 'switch_2':
|
||||||
|
return deviceStatus.switch2;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
_timer?.cancel();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
part of 'two_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class TwoGangGlassSwitchEvent {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchFetchDeviceEvent extends TwoGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchFetchDeviceEvent(this.deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchControl extends TwoGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchControl({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchControl extends TwoGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
final String code;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBatchControl({
|
||||||
|
required this.deviceIds,
|
||||||
|
required this.code,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchFetchBatchStatusEvent extends TwoGangGlassSwitchEvent {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchFetchBatchStatusEvent(this.deviceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassFactoryReset extends TwoGangGlassSwitchEvent {
|
||||||
|
final String deviceId;
|
||||||
|
final FactoryResetModel factoryReset;
|
||||||
|
|
||||||
|
TwoGangGlassFactoryReset({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.factoryReset,
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
part of 'two_gang_glass_switch_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class TwoGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchInitial extends TwoGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchLoading extends TwoGangGlassSwitchState {}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchStatusLoaded extends TwoGangGlassSwitchState {
|
||||||
|
final TwoGangGlassStatusModel status;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchError extends TwoGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchError(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchStatusLoaded extends TwoGangGlassSwitchState {
|
||||||
|
final TwoGangGlassStatusModel status;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBatchStatusLoaded(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchControlError extends TwoGangGlassSwitchState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
TwoGangGlassSwitchBatchControlError(this.message);
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassStatusModel {
|
||||||
|
final String uuid;
|
||||||
|
final bool switch1;
|
||||||
|
final int countDown1;
|
||||||
|
final bool switch2;
|
||||||
|
final int countDown2;
|
||||||
|
|
||||||
|
TwoGangGlassStatusModel({
|
||||||
|
required this.uuid,
|
||||||
|
required this.switch1,
|
||||||
|
required this.countDown1,
|
||||||
|
required this.switch2,
|
||||||
|
required this.countDown2,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TwoGangGlassStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||||
|
late bool switch1;
|
||||||
|
late int countDown1;
|
||||||
|
late bool switch2;
|
||||||
|
late int countDown2;
|
||||||
|
|
||||||
|
for (var status in jsonList) {
|
||||||
|
switch (status.code) {
|
||||||
|
case 'switch_1':
|
||||||
|
switch1 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_1':
|
||||||
|
countDown1 = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
case 'switch_2':
|
||||||
|
switch2 = status.value ?? false;
|
||||||
|
break;
|
||||||
|
case 'countdown_2':
|
||||||
|
countDown2 = status.value ?? 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TwoGangGlassStatusModel(
|
||||||
|
uuid: id,
|
||||||
|
switch1: switch1,
|
||||||
|
countDown1: countDown1,
|
||||||
|
switch2: switch2,
|
||||||
|
countDown2: countDown2,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoGangGlassStatusModel copyWith({
|
||||||
|
String? uuid,
|
||||||
|
bool? switch1,
|
||||||
|
int? countDown1,
|
||||||
|
bool? switch2,
|
||||||
|
int? countDown2,
|
||||||
|
}) {
|
||||||
|
return TwoGangGlassStatusModel(
|
||||||
|
uuid: uuid ?? this.uuid,
|
||||||
|
switch1: switch1 ?? this.switch1,
|
||||||
|
countDown1: countDown1 ?? this.countDown1,
|
||||||
|
switch2: switch2 ?? this.switch2,
|
||||||
|
countDown2: countDown2 ?? this.countDown2,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'TwoGangGlassStatusModel(uuid: $uuid, switch1: $switch1, countDown1: $countDown1, switch2: $switch2, countDown2: $countDown2)';
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final List<String> deviceIds;
|
||||||
|
|
||||||
|
const TwoGangGlassSwitchBatchControlView({required this.deviceIds, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
TwoGangGlassSwitchBloc(deviceId: deviceIds.first)..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)),
|
||||||
|
child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is TwoGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is TwoGangGlassSwitchBatchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is TwoGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Wall Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch2,
|
||||||
|
code: 'switch_2',
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
label: 'Ceiling Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchBatchControl(
|
||||||
|
deviceIds: deviceIds,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FirmwareUpdateWidget(
|
||||||
|
deviceId: deviceIds.first,
|
||||||
|
version: 12, // adjust the version according to your requirement
|
||||||
|
),
|
||||||
|
FactoryResetWidget(
|
||||||
|
callFactoryReset: () {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassFactoryReset(
|
||||||
|
deviceId: status.uuid,
|
||||||
|
factoryReset: FactoryResetModel(devicesUuid: deviceIds),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
|
class TwoGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
const TwoGangGlassSwitchControlView({required this.deviceId, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
TwoGangGlassSwitchBloc(deviceId: deviceId)..add(TwoGangGlassSwitchFetchDeviceEvent(deviceId)),
|
||||||
|
child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state is TwoGangGlassSwitchLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (state is TwoGangGlassSwitchStatusLoaded) {
|
||||||
|
return _buildStatusControls(context, state.status);
|
||||||
|
} else if (state is TwoGangGlassSwitchError) {
|
||||||
|
return const Center(child: Text('Error fetching status'));
|
||||||
|
} else {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusControls(BuildContext context, TwoGangGlassStatusModel status) {
|
||||||
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
|
final isLarge = isLargeScreenSize(context);
|
||||||
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
return GridView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: isLarge || isExtraLarge
|
||||||
|
? 3
|
||||||
|
: isMedium
|
||||||
|
? 2
|
||||||
|
: 1,
|
||||||
|
mainAxisExtent: 140,
|
||||||
|
crossAxisSpacing: 12,
|
||||||
|
mainAxisSpacing: 12,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch1,
|
||||||
|
code: 'switch_1',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Wall Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: status.switch2,
|
||||||
|
code: 'switch_2',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Ceiling Light',
|
||||||
|
onChange: (value) {
|
||||||
|
context.read<TwoGangGlassSwitchBloc>().add(
|
||||||
|
TwoGangGlassSwitchControl(
|
||||||
|
deviceId: deviceId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: false,
|
||||||
|
code: '',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Preferences',
|
||||||
|
icon: Assets.preferences,
|
||||||
|
onChange: (value) {},
|
||||||
|
showToggle: false,
|
||||||
|
),
|
||||||
|
ToggleWidget(
|
||||||
|
value: false,
|
||||||
|
code: '',
|
||||||
|
deviceId: deviceId,
|
||||||
|
label: 'Scheduling',
|
||||||
|
icon: Assets.scheduling,
|
||||||
|
onChange: (value) {},
|
||||||
|
showToggle: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -96,7 +96,7 @@ class WallSensorBatchControlView extends StatelessWidget
|
|||||||
minValue: 10,
|
minValue: 10,
|
||||||
maxValue: 10000,
|
maxValue: 10000,
|
||||||
steps: 1,
|
steps: 1,
|
||||||
description: 'hr',
|
description: 'sec',
|
||||||
action: (int value) =>
|
action: (int value) =>
|
||||||
context.read<WallSensorBloc>().add(WallSensorBatchControlEvent(
|
context.read<WallSensorBloc>().add(WallSensorBatchControlEvent(
|
||||||
deviceIds: devicesIds,
|
deviceIds: devicesIds,
|
||||||
|
@ -135,7 +135,7 @@ class WallSensorControlsView extends StatelessWidget
|
|||||||
minValue: 10,
|
minValue: 10,
|
||||||
maxValue: 10000,
|
maxValue: 10000,
|
||||||
steps: 1,
|
steps: 1,
|
||||||
description: 'hr',
|
description: 'sec',
|
||||||
action: (int value) =>
|
action: (int value) =>
|
||||||
context.read<WallSensorBloc>().add(WallSensorChangeValueEvent(
|
context.read<WallSensorBloc>().add(WallSensorChangeValueEvent(
|
||||||
code: 'no_one_time',
|
code: 'no_one_time',
|
||||||
|
@ -65,6 +65,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
Emitter<WaterHeaterState> emit,
|
Emitter<WaterHeaterState> emit,
|
||||||
) {
|
) {
|
||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
|
|
||||||
emit(currentState.copyWith(selectedTime: event.selectedTime));
|
emit(currentState.copyWith(selectedTime: event.selectedTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +76,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
final updatedDays = List<bool>.from(currentState.selectedDays);
|
final updatedDays = List<bool>.from(currentState.selectedDays);
|
||||||
updatedDays[event.index] = event.value;
|
updatedDays[event.index] = event.value;
|
||||||
emit(currentState.copyWith(selectedDays: updatedDays));
|
emit(currentState.copyWith(
|
||||||
|
selectedDays: updatedDays, selectedTime: currentState.selectedTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _updateFunctionOn(
|
FutureOr<void> _updateFunctionOn(
|
||||||
@ -83,7 +85,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
Emitter<WaterHeaterState> emit,
|
Emitter<WaterHeaterState> emit,
|
||||||
) {
|
) {
|
||||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||||
emit(currentState.copyWith(functionOn: event.isOn));
|
emit(currentState.copyWith(
|
||||||
|
functionOn: event.isOn, selectedTime: currentState.selectedTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _updateScheduleEvent(
|
FutureOr<void> _updateScheduleEvent(
|
||||||
|
@ -130,7 +130,7 @@ class InitializeAddScheduleEvent extends WaterHeaterEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class UpdateSelectedTimeEvent extends WaterHeaterEvent {
|
class UpdateSelectedTimeEvent extends WaterHeaterEvent {
|
||||||
final TimeOfDay selectedTime;
|
final TimeOfDay? selectedTime;
|
||||||
|
|
||||||
const UpdateSelectedTimeEvent(this.selectedTime);
|
const UpdateSelectedTimeEvent(this.selectedTime);
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class WaterHeaterDeviceStatusLoaded extends WaterHeaterState {
|
|||||||
isInchingActive: isInchingActive ?? this.isInchingActive,
|
isInchingActive: isInchingActive ?? this.isInchingActive,
|
||||||
schedules: schedules ?? this.schedules,
|
schedules: schedules ?? this.schedules,
|
||||||
selectedDays: selectedDays ?? this.selectedDays,
|
selectedDays: selectedDays ?? this.selectedDays,
|
||||||
selectedTime: selectedTime ?? this.selectedTime,
|
selectedTime: selectedTime,
|
||||||
functionOn: functionOn ?? this.functionOn,
|
functionOn: functionOn ?? this.functionOn,
|
||||||
isEditing: isEditing ?? this.isEditing,
|
isEditing: isEditing ?? this.isEditing,
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,15 @@ class ScheduleDialogHelper {
|
|||||||
{ScheduleModel? schedule, int? index, bool? isEdit}) {
|
{ScheduleModel? schedule, int? index, bool? isEdit}) {
|
||||||
final bloc = context.read<WaterHeaterBloc>();
|
final bloc = context.read<WaterHeaterBloc>();
|
||||||
|
|
||||||
if (schedule != null) {
|
if (schedule == null) {
|
||||||
|
bloc.add((const UpdateSelectedTimeEvent(null)));
|
||||||
|
bloc.add(InitializeAddScheduleEvent(
|
||||||
|
selectedTime: null,
|
||||||
|
selectedDays: List.filled(7, false),
|
||||||
|
functionOn: false,
|
||||||
|
isEditing: false,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
final time = _convertStringToTimeOfDay(schedule.time);
|
final time = _convertStringToTimeOfDay(schedule.time);
|
||||||
final selectedDays = _convertDaysStringToBooleans(schedule.days);
|
final selectedDays = _convertDaysStringToBooleans(schedule.days);
|
||||||
|
|
||||||
@ -22,16 +30,6 @@ class ScheduleDialogHelper {
|
|||||||
isEditing: true,
|
isEditing: true,
|
||||||
index: index,
|
index: index,
|
||||||
));
|
));
|
||||||
} else {
|
|
||||||
bloc.add(
|
|
||||||
const InitializeAddScheduleEvent(
|
|
||||||
selectedDays: [false, false, false, false, false, false, false],
|
|
||||||
functionOn: false,
|
|
||||||
isEditing: false,
|
|
||||||
index: null,
|
|
||||||
selectedTime: null,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showDialog(
|
showDialog(
|
||||||
@ -183,7 +181,7 @@ class ScheduleDialogHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static List<bool> _convertDaysStringToBooleans(List<String> selectedDays) {
|
static List<bool> _convertDaysStringToBooleans(List<String> selectedDays) {
|
||||||
final daysOfWeek = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
final daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||||
List<bool> daysBoolean = List.filled(7, false);
|
List<bool> daysBoolean = List.filled(7, false);
|
||||||
|
|
||||||
for (int i = 0; i < daysOfWeek.length; i++) {
|
for (int i = 0; i < daysOfWeek.length; i++) {
|
||||||
@ -198,7 +196,7 @@ class ScheduleDialogHelper {
|
|||||||
static Widget _buildDayCheckboxes(
|
static Widget _buildDayCheckboxes(
|
||||||
BuildContext context, List<bool> selectedDays,
|
BuildContext context, List<bool> selectedDays,
|
||||||
{bool? isEdit}) {
|
{bool? isEdit}) {
|
||||||
final dayLabels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
children: List.generate(7, (index) {
|
children: List.generate(7, (index) {
|
||||||
|
@ -62,6 +62,7 @@ class WaterHeaterDeviceControlView extends StatelessWidget
|
|||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
value: status.heaterSwitch,
|
value: status.heaterSwitch,
|
||||||
|
icon: Assets.waterHeater,
|
||||||
label: 'Water Heater',
|
label: 'Water Heater',
|
||||||
onChange: (value) {
|
onChange: (value) {
|
||||||
context.read<WaterHeaterBloc>().add(ToggleWaterHeaterEvent(
|
context.read<WaterHeaterBloc>().add(ToggleWaterHeaterEvent(
|
||||||
|
@ -24,6 +24,7 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final bloc = BlocProvider.of<WaterHeaterBloc>(context);
|
final bloc = BlocProvider.of<WaterHeaterBloc>(context);
|
||||||
|
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: bloc,
|
value: bloc,
|
||||||
child: Dialog(
|
child: Dialog(
|
||||||
@ -51,12 +52,13 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
if (state.scheduleMode == ScheduleModes.schedule)
|
if (state.scheduleMode == ScheduleModes.schedule)
|
||||||
ScheduleManagementUI(
|
ScheduleManagementUI(
|
||||||
state: state,
|
state: state,
|
||||||
onAddSchedule: () =>
|
onAddSchedule: () {
|
||||||
ScheduleDialogHelper.showAddScheduleDialog(
|
ScheduleDialogHelper.showAddScheduleDialog(
|
||||||
context,
|
context,
|
||||||
schedule: null,
|
schedule: null,
|
||||||
index: null,
|
index: null,
|
||||||
isEdit: false),
|
isEdit: false);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
if (state.scheduleMode == ScheduleModes.countdown ||
|
if (state.scheduleMode == ScheduleModes.countdown ||
|
||||||
state.scheduleMode == ScheduleModes.inching)
|
state.scheduleMode == ScheduleModes.inching)
|
||||||
|
@ -210,7 +210,7 @@ class ScheduleTableWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _getSelectedDays(List<bool> selectedDays) {
|
String _getSelectedDays(List<bool> selectedDays) {
|
||||||
final days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
final days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||||
List<String> selectedDaysStr = [];
|
List<String> selectedDaysStr = [];
|
||||||
for (int i = 0; i < selectedDays.length; i++) {
|
for (int i = 0; i < selectedDays.length; i++) {
|
||||||
if (selectedDays[i]) {
|
if (selectedDays[i]) {
|
||||||
|
@ -13,12 +13,10 @@ class Assets {
|
|||||||
static const String rightLine = "assets/images/right_line.png";
|
static const String rightLine = "assets/images/right_line.png";
|
||||||
static const String google = "assets/images/google.svg";
|
static const String google = "assets/images/google.svg";
|
||||||
static const String facebook = "assets/images/facebook.svg";
|
static const String facebook = "assets/images/facebook.svg";
|
||||||
static const String invisiblePassword =
|
static const String invisiblePassword = "assets/images/Password_invisible.svg";
|
||||||
"assets/images/Password_invisible.svg";
|
|
||||||
static const String visiblePassword = "assets/images/password_visible.svg";
|
static const String visiblePassword = "assets/images/password_visible.svg";
|
||||||
static const String accessIcon = "assets/images/access_icon.svg";
|
static const String accessIcon = "assets/images/access_icon.svg";
|
||||||
static const String spaseManagementIcon =
|
static const String spaseManagementIcon = "assets/images/spase_management_icon.svg";
|
||||||
"assets/images/spase_management_icon.svg";
|
|
||||||
static const String devicesIcon = "assets/images/devices_icon.svg";
|
static const String devicesIcon = "assets/images/devices_icon.svg";
|
||||||
static const String moveinIcon = "assets/images/movein_icon.svg";
|
static const String moveinIcon = "assets/images/movein_icon.svg";
|
||||||
static const String constructionIcon = "assets/images/construction_icon.svg";
|
static const String constructionIcon = "assets/images/construction_icon.svg";
|
||||||
@ -31,15 +29,13 @@ class Assets {
|
|||||||
static const String emptyTable = "assets/images/empty_table.svg";
|
static const String emptyTable = "assets/images/empty_table.svg";
|
||||||
|
|
||||||
// General assets
|
// General assets
|
||||||
static const String motionlessDetection =
|
static const String motionlessDetection = "assets/icons/motionless_detection.svg";
|
||||||
"assets/icons/motionless_detection.svg";
|
|
||||||
static const String acHeating = "assets/icons/ac_heating.svg";
|
static const String acHeating = "assets/icons/ac_heating.svg";
|
||||||
static const String acPowerOff = "assets/icons/ac_power_off.svg";
|
static const String acPowerOff = "assets/icons/ac_power_off.svg";
|
||||||
static const String acFanMiddle = "assets/icons/ac_fan_middle.svg";
|
static const String acFanMiddle = "assets/icons/ac_fan_middle.svg";
|
||||||
static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg";
|
static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg";
|
||||||
static const String resetOff = "assets/icons/reset_off.svg";
|
static const String resetOff = "assets/icons/reset_off.svg";
|
||||||
static const String sensitivityOperationIcon =
|
static const String sensitivityOperationIcon = "assets/icons/sesitivity_operation_icon.svg";
|
||||||
"assets/icons/sesitivity_operation_icon.svg";
|
|
||||||
static const String motionDetection = "assets/icons/motion_detection.svg";
|
static const String motionDetection = "assets/icons/motion_detection.svg";
|
||||||
static const String freezing = "assets/icons/freezing.svg";
|
static const String freezing = "assets/icons/freezing.svg";
|
||||||
static const String indicator = "assets/icons/indicator.svg";
|
static const String indicator = "assets/icons/indicator.svg";
|
||||||
@ -60,56 +56,35 @@ class Assets {
|
|||||||
static const String celsiusDegrees = "assets/icons/celsius_degrees.svg";
|
static const String celsiusDegrees = "assets/icons/celsius_degrees.svg";
|
||||||
static const String masterState = "assets/icons/master_state.svg";
|
static const String masterState = "assets/icons/master_state.svg";
|
||||||
static const String acPower = "assets/icons/ac_power.svg";
|
static const String acPower = "assets/icons/ac_power.svg";
|
||||||
static const String farDetectionFunction =
|
static const String farDetectionFunction = "assets/icons/far_detection_function.svg";
|
||||||
"assets/icons/far_detection_function.svg";
|
|
||||||
static const String nobodyTime = "assets/icons/nobody_time.svg";
|
static const String nobodyTime = "assets/icons/nobody_time.svg";
|
||||||
|
|
||||||
// Automation functions
|
// Automation functions
|
||||||
static const String tempPasswordUnlock =
|
static const String tempPasswordUnlock = "assets/icons/automation_functions/temp_password_unlock.svg";
|
||||||
"assets/icons/automation_functions/temp_password_unlock.svg";
|
static const String doorlockNormalOpen = "assets/icons/automation_functions/doorlock_normal_open.svg";
|
||||||
static const String doorlockNormalOpen =
|
static const String doorbell = "assets/icons/automation_functions/doorbell.svg";
|
||||||
"assets/icons/automation_functions/doorlock_normal_open.svg";
|
static const String remoteUnlockViaApp = "assets/icons/automation_functions/remote_unlock_via_app.svg";
|
||||||
static const String doorbell =
|
static const String doubleLock = "assets/icons/automation_functions/double_lock.svg";
|
||||||
"assets/icons/automation_functions/doorbell.svg";
|
static const String selfTestResult = "assets/icons/automation_functions/self_test_result.svg";
|
||||||
static const String remoteUnlockViaApp =
|
static const String lockAlarm = "assets/icons/automation_functions/lock_alarm.svg";
|
||||||
"assets/icons/automation_functions/remote_unlock_via_app.svg";
|
static const String presenceState = "assets/icons/automation_functions/presence_state.svg";
|
||||||
static const String doubleLock =
|
static const String currentTemp = "assets/icons/automation_functions/current_temp.svg";
|
||||||
"assets/icons/automation_functions/double_lock.svg";
|
static const String presence = "assets/icons/automation_functions/presence.svg";
|
||||||
static const String selfTestResult =
|
static const String residualElectricity = "assets/icons/automation_functions/residual_electricity.svg";
|
||||||
"assets/icons/automation_functions/self_test_result.svg";
|
static const String hijackAlarm = "assets/icons/automation_functions/hijack_alarm.svg";
|
||||||
static const String lockAlarm =
|
static const String passwordUnlock = "assets/icons/automation_functions/password_unlock.svg";
|
||||||
"assets/icons/automation_functions/lock_alarm.svg";
|
static const String remoteUnlockRequest = "assets/icons/automation_functions/remote_unlock_req.svg";
|
||||||
static const String presenceState =
|
static const String cardUnlock = "assets/icons/automation_functions/card_unlock.svg";
|
||||||
"assets/icons/automation_functions/presence_state.svg";
|
|
||||||
static const String currentTemp =
|
|
||||||
"assets/icons/automation_functions/current_temp.svg";
|
|
||||||
static const String presence =
|
|
||||||
"assets/icons/automation_functions/presence.svg";
|
|
||||||
static const String residualElectricity =
|
|
||||||
"assets/icons/automation_functions/residual_electricity.svg";
|
|
||||||
static const String hijackAlarm =
|
|
||||||
"assets/icons/automation_functions/hijack_alarm.svg";
|
|
||||||
static const String passwordUnlock =
|
|
||||||
"assets/icons/automation_functions/password_unlock.svg";
|
|
||||||
static const String remoteUnlockRequest =
|
|
||||||
"assets/icons/automation_functions/remote_unlock_req.svg";
|
|
||||||
static const String cardUnlock =
|
|
||||||
"assets/icons/automation_functions/card_unlock.svg";
|
|
||||||
static const String motion = "assets/icons/automation_functions/motion.svg";
|
static const String motion = "assets/icons/automation_functions/motion.svg";
|
||||||
static const String fingerprintUnlock =
|
static const String fingerprintUnlock = "assets/icons/automation_functions/fingerprint_unlock.svg";
|
||||||
"assets/icons/automation_functions/fingerprint_unlock.svg";
|
|
||||||
|
|
||||||
// Presence Sensor Assets
|
// Presence Sensor Assets
|
||||||
static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg";
|
static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg";
|
||||||
static const String sensorPresenceIcon =
|
static const String sensorPresenceIcon = "assets/icons/sensor_presence_ic.svg";
|
||||||
"assets/icons/sensor_presence_ic.svg";
|
|
||||||
static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg";
|
static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg";
|
||||||
static const String illuminanceRecordIcon =
|
static const String illuminanceRecordIcon = "assets/icons/illuminance_record_ic.svg";
|
||||||
"assets/icons/illuminance_record_ic.svg";
|
static const String presenceRecordIcon = "assets/icons/presence_record_ic.svg";
|
||||||
static const String presenceRecordIcon =
|
static const String helpDescriptionIcon = "assets/icons/help_description_ic.svg";
|
||||||
"assets/icons/presence_record_ic.svg";
|
|
||||||
static const String helpDescriptionIcon =
|
|
||||||
"assets/icons/help_description_ic.svg";
|
|
||||||
|
|
||||||
static const String lightPulp = "assets/icons/light_pulb.svg";
|
static const String lightPulp = "assets/icons/light_pulb.svg";
|
||||||
static const String acDevice = "assets/icons/ac_device.svg";
|
static const String acDevice = "assets/icons/ac_device.svg";
|
||||||
@ -166,4 +141,13 @@ class Assets {
|
|||||||
|
|
||||||
//assets/icons/water_heater.svg
|
//assets/icons/water_heater.svg
|
||||||
static const String waterHeater = 'assets/icons/water_heater.svg';
|
static const String waterHeater = 'assets/icons/water_heater.svg';
|
||||||
|
|
||||||
|
//assets/icons/ac_lock.svg
|
||||||
|
static const String acLock = 'assets/icons/ac_lock.svg';
|
||||||
|
|
||||||
|
//assets/icons/ac_schedule.svg
|
||||||
|
static const String acSchedule = 'assets/icons/ac_schedule.svg';
|
||||||
|
|
||||||
|
//assets/icons/preferences.svg
|
||||||
|
static const String preferences = 'assets/icons/preferences.svg';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user