Compare commits

..

5 Commits

Author SHA1 Message Date
48327fbbe5 sos 2024-11-14 10:23:00 +03:00
6920d9129e sos 2024-11-14 10:14:28 +03:00
44965d8928 SOS 2024-11-14 09:34:33 +03:00
93f6489d22 sos 2024-11-13 14:54:05 +03:00
69de4b4c00 sos_device 2024-11-13 14:19:50 +03:00
81 changed files with 1614 additions and 7428 deletions

View File

@ -1,5 +0,0 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="9" cy="9" r="9" fill="#7CC67B"/>
<line x1="3" y1="9" x2="15" y2="9" stroke="white" stroke-width="2"/>
<line x1="9" y1="3" x2="9" y2="15" stroke="white" stroke-width="2"/>
</svg>

Before

Width:  |  Height:  |  Size: 286 B

View File

@ -1,5 +0,0 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 0V36C27.9411 36 36 27.9411 36 18C36 8.05886 27.9411 0 18 0Z" fill="#3B88F5"/>
<path d="M33.827 18C33.827 8.05886 26.741 0 18 0C8.05886 0 0 8.05886 0 18C0 27.9411 8.05886 36 18 36C26.741 36 33.827 27.9411 33.827 18Z" fill="#28ABFA"/>
<path d="M25.2749 19.8827C25.8404 19.5071 26.2213 18.805 26.2213 18.0002C26.2213 17.1953 25.8404 16.4932 25.2749 16.1177C25.2749 16.1169 14.5527 8.99908 14.5527 8.99908C14.3036 8.83407 14.0248 8.73643 13.7391 8.71289C13.4191 8.73469 13.0992 8.82726 12.8027 8.99843C12.1057 9.40087 11.7166 10.1312 11.7165 10.882C11.7158 10.8824 11.7158 25.1181 11.7158 25.1181C11.7166 25.8693 12.1057 26.5996 12.8027 27.002C13.099 27.1731 13.419 27.2657 13.7387 27.2875C14.0245 27.264 14.3032 27.1662 14.5521 27.001L25.2749 19.8827Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 881 B

View File

@ -1,10 +0,0 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_4487_8092)">
<path d="M9.75 5.25H8.25V8.25H5.25V9.75H8.25V12.75H9.75V9.75H12.75V8.25H9.75V5.25ZM9 1.5C4.86 1.5 1.5 4.86 1.5 9C1.5 13.14 4.86 16.5 9 16.5C13.14 16.5 16.5 13.14 16.5 9C16.5 4.86 13.14 1.5 9 1.5ZM9 15C5.6925 15 3 12.3075 3 9C3 5.6925 5.6925 3 9 3C12.3075 3 15 5.6925 15 9C15 12.3075 12.3075 15 9 15Z" fill="#6488FB"/>
</g>
<defs>
<clipPath id="clip0_4487_8092">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 567 B

View File

@ -1,10 +0,0 @@
<svg width="48" height="49" viewBox="0 0 48 49" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M29.5377 41.3253V44.6226C29.5377 47.0444 27.6825 48.9996 25.384 48.9996H22.6148C20.3163 48.9996 18.4611 47.0444 18.4611 44.6226V41.3253C18.4611 40.5082 19.0702 39.769 19.8456 39.769H28.1531C28.9286 39.769 29.5377 40.5082 29.5377 41.3253Z" fill="#FEA832"/>
<path d="M29.5377 41.3253V44.6226C29.5377 47.0444 27.6825 48.9996 25.384 48.9996H23.9994V39.769H28.1531C28.9286 39.769 29.5377 40.5082 29.5377 41.3253Z" fill="#FE9923"/>
<path d="M23.996 12.0776C22.9619 12.0776 21.9279 12.1913 20.8936 12.4474C16.2977 13.4999 12.5923 17.1122 11.4719 21.635C10.3517 26.1861 11.6443 30.7941 14.9476 34.0083C16.1254 35.1747 16.8148 36.9097 16.8148 38.7871V39.1C16.8148 41.4608 18.7392 43.4615 21.1235 43.4615H26.8685C29.2528 43.4615 31.1772 41.4608 31.1772 39.1V38.7871C31.1772 36.9381 31.8953 35.1461 33.1592 33.923C35.5722 31.5052 36.9222 28.2911 36.9222 24.8777C36.9222 17.7096 31.0624 12.0776 23.996 12.0776Z" fill="#FEDB41"/>
<path d="M11.0733 14.0625L7.09628 10.0855C6.54701 9.53623 6.54701 8.64628 7.09628 8.09701C7.64555 7.54774 8.5355 7.54774 9.08477 8.09701L13.0618 12.074C13.611 12.6233 13.611 13.5132 13.0618 14.0625C12.5125 14.6118 11.6226 14.6118 11.0733 14.0625Z" fill="#FEA832"/>
<path d="M7.12498 26.4077H1.40634C0.629078 26.4077 0.00012207 25.7787 0.00012207 25.0014C0.00012207 24.2242 0.629078 23.5952 1.40634 23.5952H7.12498C7.90225 23.5952 8.5312 24.2242 8.5312 25.0014C8.5312 25.7787 7.90225 26.4077 7.12498 26.4077Z" fill="#FEA832"/>
<path d="M46.5931 26.4077H40.8745C40.0972 26.4077 39.4683 25.7787 39.4683 25.0014C39.4683 24.2242 40.0972 23.5952 40.8745 23.5952H46.5931C47.3704 23.5952 47.9993 24.2242 47.9993 25.0014C47.9993 25.7787 47.3704 26.4077 46.5931 26.4077Z" fill="#FE9923"/>
<path d="M34.9375 14.0625C34.3882 13.5132 34.3882 12.6233 34.9375 12.074L38.9144 8.09701C39.4637 7.54774 40.3537 7.54774 40.9029 8.09701C41.4522 8.64628 41.4522 9.53623 40.9029 10.0855L36.926 14.0625C36.3766 14.6118 35.4867 14.6118 34.9375 14.0625Z" fill="#FE9923"/>
<path d="M23.8009 9.01898C23.0241 9.01898 22.3948 8.38969 22.3948 7.6129V1.9886C22.3948 1.21181 23.0241 0.58252 23.8009 0.58252C24.5776 0.58252 25.2069 1.21181 25.2069 1.9886L25.2069 7.6129C25.2069 8.38982 24.5777 9.01904 23.8009 9.01898Z" fill="#FE9923"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,3 +0,0 @@
<svg width="20" height="16" viewBox="0 0 20 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.3334 2.50008H10L8.16671 0.666748H2.66671C1.64921 0.666748 0.842541 1.48258 0.842541 2.50008L0.833374 13.5001C0.833374 14.5176 1.64921 15.3334 2.66671 15.3334H17.3334C18.3509 15.3334 19.1667 14.5176 19.1667 13.5001V4.33341C19.1667 3.31591 18.3509 2.50008 17.3334 2.50008ZM17.3334 13.5001H2.66671V2.50008H7.40587L9.23921 4.33341H17.3334V13.5001ZM10 9.83342H11.8334V11.6667H13.6667V9.83342H15.5V8.00008H13.6667V6.16675H11.8334V8.00008H10V9.83342Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 576 B

View File

@ -1,10 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_4487_7077)">
<path d="M14.06 9.02L14.98 9.94L5.92 19H5V18.08L14.06 9.02ZM17.66 3C17.41 3 17.15 3.1 16.96 3.29L15.13 5.12L18.88 8.87L20.71 7.04C21.1 6.65 21.1 6.02 20.71 5.63L18.37 3.29C18.17 3.09 17.92 3 17.66 3ZM14.06 6.19L3 17.25V21H6.75L17.81 9.94L14.06 6.19Z" fill="#999999"/>
</g>
<defs>
<clipPath id="clip0_4487_7077">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 517 B

View File

@ -1,9 +0,0 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555643 0.555643 0 1.24111 0H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79675 39.5036 2.48221L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
<path d="M38.7589 0H35.0356C35.721 0 36.2767 0.555643 36.2767 1.24111V38.7589C36.2767 39.4444 35.721 40 35.0356 40H38.7589C39.4444 40 40 39.4444 40 38.7589V1.24111C40 0.555643 39.4444 0 38.7589 0Z" fill="#D1D1D1"/>
<path opacity="0.6" d="M12.0284 31.8319V33.3213C12.0284 34.0067 11.6087 34.5624 11.0909 34.5624H6.96594C6.44816 34.5624 6.02844 34.0067 6.02844 33.3213V31.8319C6.02844 31.1465 6.44816 30.5908 6.96594 30.5908H11.0909C11.6087 30.5908 12.0284 31.1465 12.0284 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M12.0284 7.24111V8.73044C12.0284 9.4159 11.6087 9.97154 11.0909 9.97154H6.96594C6.44816 9.97154 6.02844 9.4159 6.02844 8.73044V7.24111C6.02844 6.55565 6.44816 6 6.96594 6H11.0909C11.6087 6 12.0284 6.55565 12.0284 7.24111Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M26.0285 31.8319V33.3213C26.0285 34.0067 26.4482 34.5624 26.966 34.5624H31.091C31.6088 34.5624 32.0285 34.0067 32.0285 33.3213V31.8319C32.0285 31.1465 31.6088 30.5908 31.091 30.5908H26.966C26.4482 30.5908 26.0285 31.1465 26.0285 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M26.0285 7.24111V8.73044C26.0285 9.4159 26.4482 9.97154 26.966 9.97154H31.091C31.6088 9.97154 32.0285 9.4159 32.0285 8.73044V7.24111C32.0285 6.55565 31.6088 6 31.091 6H26.966C26.4482 6 26.0285 6.55565 26.0285 7.24111Z" fill="#023DFE" fill-opacity="0.5"/>
<path d="M19.0691 0H20.9308V40H19.0691V0Z" fill="#D1D1D1"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,67 +0,0 @@
<svg width="92" height="97" viewBox="0 0 92 97" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_4487_4172)">
<path d="M8.65399 9.63292C8.65399 8.1788 9.83279 7 11.2869 7H81.0593C82.5134 7 83.6922 8.1788 83.6922 9.63292V72.823C83.6922 74.2771 82.5134 75.4559 81.0593 75.4559H11.2869C9.83279 75.4559 8.65399 74.2771 8.65399 72.823V9.63292Z" fill="white"/>
</g>
<g filter="url(#filter1_d_4487_4172)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M81.0593 7.26329H11.2869C9.9782 7.26329 8.91728 8.32421 8.91728 9.63292V72.823C8.91728 74.1317 9.9782 75.1926 11.2869 75.1926H81.0593C82.368 75.1926 83.4289 74.1317 83.4289 72.823V9.63292C83.4289 8.32421 82.368 7.26329 81.0593 7.26329ZM11.2869 7C9.83279 7 8.65399 8.1788 8.65399 9.63292V72.823C8.65399 74.2771 9.83279 75.4559 11.2869 75.4559H81.0593C82.5134 75.4559 83.6922 74.2771 83.6922 72.823V9.63292C83.6922 8.1788 82.5134 7 81.0593 7H11.2869Z" fill="#E4E4E4"/>
</g>
<g filter="url(#filter2_d_4487_4172)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.1726 75.1923L46.1726 7.26294H46.4359L46.4359 75.1923H46.1726Z" fill="#E4E4E4"/>
</g>
<path d="M26.8888 18.4212C26.8895 18.4654 26.9031 18.5083 26.9279 18.5448C26.9527 18.5813 26.9876 18.6098 27.0284 18.6267C27.3928 18.7871 27.7009 19.0527 27.9133 19.3894C28.1257 19.7262 28.2325 20.1187 28.2202 20.5167C28.2116 21.0463 27.993 21.5509 27.6123 21.9194C27.2317 22.2878 26.7203 22.49 26.1907 22.4814C25.661 22.4728 25.1564 22.2541 24.788 21.8735C24.4195 21.4929 24.2174 20.9815 24.2259 20.4519C24.2265 20.0649 24.3394 19.6864 24.551 19.3625C24.7625 19.0385 25.0637 18.783 25.4178 18.6269C25.4586 18.6099 25.4935 18.5814 25.5183 18.5448C25.5431 18.5082 25.5567 18.4652 25.5574 18.421C25.5574 18.3847 25.5485 18.3489 25.5315 18.3167C25.5145 18.2846 25.4899 18.2572 25.4598 18.2368C25.4296 18.2165 25.395 18.2038 25.3589 18.2C25.3227 18.1962 25.2862 18.2013 25.2525 18.2149C24.7375 18.4381 24.3152 18.832 24.0567 19.3303C23.7982 19.8285 23.7193 20.4006 23.8334 20.9502C23.9474 21.4998 24.2473 21.9933 24.6826 22.3476C25.118 22.7019 25.6621 22.8953 26.2234 22.8953C26.7847 22.8953 27.3288 22.7019 27.7642 22.3476C28.1995 21.9933 28.4994 21.4998 28.6135 20.9502C28.7275 20.4006 28.6486 19.8285 28.3901 19.3303C28.1316 18.832 27.7093 18.4381 27.1943 18.2149C27.1606 18.2011 27.124 18.1959 27.0877 18.1997C27.0515 18.2035 27.0167 18.2161 26.9865 18.2365C26.9563 18.2569 26.9316 18.2844 26.9145 18.3166C26.8975 18.3489 26.8886 18.3848 26.8888 18.4212Z" fill="#6488FB"/>
<path d="M26.4447 17.7893C26.4447 17.6667 26.3453 17.5674 26.2228 17.5674C26.1002 17.5674 26.0009 17.6667 26.0009 17.7893V19.1207C26.0009 19.2433 26.1002 19.3426 26.2228 19.3426C26.3453 19.3426 26.4447 19.2433 26.4447 19.1207V17.7893Z" fill="#6488FB"/>
<path d="M26.8884 60.2491C26.8891 60.2932 26.9027 60.3362 26.9275 60.3727C26.9523 60.4092 26.9872 60.4377 27.028 60.4546C27.3924 60.6149 27.7006 60.8805 27.9129 61.2173C28.1253 61.5541 28.2322 61.9466 28.2198 62.3445C28.2112 62.8742 27.9926 63.3788 27.612 63.7472C27.2314 64.1157 26.72 64.3179 26.1903 64.3093C25.6606 64.3007 25.1561 64.082 24.7876 63.7014C24.4192 63.3208 24.217 62.8094 24.2256 62.2797C24.2261 61.8928 24.339 61.5143 24.5506 61.1904C24.7622 60.8664 25.0633 60.6108 25.4174 60.4548C25.4582 60.4378 25.4931 60.4093 25.5179 60.3727C25.5427 60.3361 25.5563 60.2931 25.557 60.2489C25.5571 60.2125 25.5482 60.1767 25.5312 60.1446C25.5141 60.1125 25.4895 60.0851 25.4594 60.0647C25.4293 60.0444 25.3946 60.0317 25.3585 60.0279C25.3223 60.024 25.2858 60.0291 25.2521 60.0427C24.7371 60.266 24.3148 60.6599 24.0563 61.1582C23.7979 61.6564 23.719 62.2285 23.833 62.7781C23.947 63.3276 24.2469 63.8212 24.6823 64.1755C25.1176 64.5297 25.6617 64.7232 26.223 64.7232C26.7843 64.7232 27.3285 64.5297 27.7638 64.1755C28.1991 63.8212 28.4991 63.3276 28.6131 62.7781C28.7271 62.2285 28.6482 61.6564 28.3897 61.1582C28.1312 60.6599 27.7089 60.266 27.194 60.0427C27.1602 60.029 27.1236 60.0238 27.0873 60.0276C27.0511 60.0313 27.0163 60.044 26.9861 60.0644C26.9559 60.0848 26.9312 60.1123 26.9142 60.1445C26.8971 60.1767 26.8883 60.2127 26.8884 60.2491Z" fill="#6488FB"/>
<path d="M26.4443 59.6167C26.4443 59.4941 26.3449 59.3948 26.2224 59.3948C26.0998 59.3948 26.0005 59.4941 26.0005 59.6167V60.9481C26.0005 61.0706 26.0998 61.17 26.2224 61.17C26.3449 61.17 26.4443 61.0706 26.4443 60.9481V59.6167Z" fill="#6488FB"/>
<path d="M65.9977 18.4212C65.9984 18.4654 66.0119 18.5083 66.0367 18.5448C66.0615 18.5813 66.0965 18.6098 66.1372 18.6267C66.5017 18.7871 66.8098 19.0527 67.0222 19.3894C67.2346 19.7262 67.3414 20.1187 67.3291 20.5167C67.3205 21.0463 67.1018 21.5509 66.7212 21.9194C66.3406 22.2878 65.8292 22.49 65.2996 22.4814C64.7699 22.4728 64.2653 22.2541 63.8969 21.8735C63.5284 21.4929 63.3262 20.9815 63.3348 20.4519C63.3353 20.0649 63.4483 19.6864 63.6598 19.3625C63.8714 19.0385 64.1726 18.783 64.5267 18.6269C64.5675 18.6099 64.6024 18.5814 64.6272 18.5448C64.652 18.5082 64.6656 18.4652 64.6663 18.421C64.6663 18.3847 64.6574 18.3489 64.6404 18.3167C64.6234 18.2846 64.5987 18.2572 64.5686 18.2368C64.5385 18.2165 64.5039 18.2038 64.4677 18.2C64.4316 18.1962 64.3951 18.2013 64.3614 18.2149C63.8464 18.4381 63.4241 18.832 63.1656 19.3303C62.9071 19.8285 62.8282 20.4006 62.9422 20.9502C63.0563 21.4998 63.3562 21.9933 63.7915 22.3476C64.2269 22.7019 64.771 22.8953 65.3323 22.8953C65.8936 22.8953 66.4377 22.7019 66.8731 22.3476C67.3084 21.9933 67.6083 21.4998 67.7223 20.9502C67.8363 20.4006 67.7575 19.8285 67.499 19.3303C67.2405 18.832 66.8182 18.4381 66.3032 18.2149C66.2695 18.2011 66.2328 18.1959 66.1966 18.1997C66.1603 18.2035 66.1256 18.2161 66.0954 18.2365C66.0652 18.2569 66.0405 18.2844 66.0234 18.3166C66.0064 18.3489 65.9975 18.3848 65.9977 18.4212Z" fill="#6488FB"/>
<path d="M65.5539 17.7893C65.5539 17.6667 65.4545 17.5674 65.332 17.5674C65.2094 17.5674 65.11 17.6667 65.11 17.7893V19.1207C65.11 19.2433 65.2094 19.3426 65.332 19.3426C65.4545 19.3426 65.5539 19.2433 65.5539 19.1207V17.7893Z" fill="#6488FB"/>
<path d="M65.9977 60.2491C65.9984 60.2932 66.0119 60.3362 66.0367 60.3727C66.0615 60.4092 66.0965 60.4377 66.1372 60.4546C66.5017 60.6149 66.8098 60.8805 67.0222 61.2173C67.2346 61.5541 67.3414 61.9466 67.3291 62.3445C67.3205 62.8742 67.1018 63.3788 66.7212 63.7472C66.3406 64.1157 65.8292 64.3179 65.2996 64.3093C64.7699 64.3007 64.2653 64.082 63.8969 63.7014C63.5284 63.3208 63.3262 62.8094 63.3348 62.2797C63.3353 61.8928 63.4483 61.5143 63.6598 61.1904C63.8714 60.8664 64.1726 60.6108 64.5267 60.4548C64.5675 60.4378 64.6024 60.4093 64.6272 60.3727C64.652 60.3361 64.6656 60.2931 64.6663 60.2489C64.6663 60.2125 64.6574 60.1767 64.6404 60.1446C64.6234 60.1125 64.5987 60.0851 64.5686 60.0647C64.5385 60.0444 64.5039 60.0317 64.4677 60.0279C64.4316 60.024 64.3951 60.0291 64.3614 60.0427C63.8464 60.266 63.4241 60.6599 63.1656 61.1582C62.9071 61.6564 62.8282 62.2285 62.9422 62.7781C63.0563 63.3276 63.3562 63.8212 63.7915 64.1755C64.2269 64.5297 64.771 64.7232 65.3323 64.7232C65.8936 64.7232 66.4377 64.5297 66.8731 64.1755C67.3084 63.8212 67.6083 63.3276 67.7223 62.7781C67.8363 62.2285 67.7575 61.6564 67.499 61.1582C67.2405 60.6599 66.8182 60.266 66.3032 60.0427C66.2695 60.029 66.2328 60.0238 66.1966 60.0276C66.1603 60.0313 66.1256 60.044 66.0954 60.0644C66.0652 60.0848 66.0405 60.1123 66.0234 60.1445C66.0064 60.1767 65.9975 60.2127 65.9977 60.2491Z" fill="#6488FB"/>
<path d="M65.5539 59.6167C65.5539 59.4941 65.4545 59.3948 65.332 59.3948C65.2094 59.3948 65.11 59.4941 65.11 59.6167V60.9481C65.11 61.0706 65.2094 61.17 65.332 61.17C65.4545 61.17 65.5539 61.0706 65.5539 60.9481V59.6167Z" fill="#6488FB"/>
<g opacity="0.5" filter="url(#filter3_f_4487_4172)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.2335 71.7696L10.2335 9.36938L10.4968 9.36938L10.4968 71.7696L10.2335 71.7696Z" fill="#D3D1D1"/>
</g>
<g opacity="0.5" filter="url(#filter4_f_4487_4172)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M81.8485 71.7696L81.8485 9.36938L82.1118 9.36938L82.1118 71.7696L81.8485 71.7696Z" fill="#D3D1D1"/>
</g>
<defs>
<filter id="filter0_d_4487_4172" x="0.653992" y="0" width="91.0382" height="84.4558" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4487_4172"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4487_4172" result="shape"/>
</filter>
<filter id="filter1_d_4487_4172" x="0.653992" y="7" width="91.0382" height="89.4558" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="13"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4487_4172"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4487_4172" result="shape"/>
</filter>
<filter id="filter2_d_4487_4172" x="42.1725" y="3.26294" width="8.26331" height="75.9294" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4487_4172"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4487_4172" result="shape"/>
</filter>
<filter id="filter3_f_4487_4172" x="7.23352" y="6.36938" width="6.26331" height="68.4001" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="1.5" result="effect1_foregroundBlur_4487_4172"/>
</filter>
<filter id="filter4_f_4487_4172" x="78.8485" y="6.36938" width="6.26331" height="68.4001" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="1.5" result="effect1_foregroundBlur_4487_4172"/>
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,4 +0,0 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="9" cy="9" r="9" fill="#FF0909"/>
<line x1="3" y1="9" x2="15" y2="9" stroke="white" stroke-width="2"/>
</svg>

Before

Width:  |  Height:  |  Size: 217 B

View File

@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.24976 7.25V8.75H11.7498V7.25H4.24976ZM7.99976 0.5C3.85976 0.5 0.499756 3.86 0.499756 8C0.499756 12.14 3.85976 15.5 7.99976 15.5C12.1398 15.5 15.4998 12.14 15.4998 8C15.4998 3.86 12.1398 0.5 7.99976 0.5ZM7.99976 14C4.69226 14 1.99976 11.3075 1.99976 8C1.99976 4.6925 4.69226 2 7.99976 2C11.3073 2 13.9998 4.6925 13.9998 8C13.9998 11.3075 11.3073 14 7.99976 14Z" fill="#FF2F2F"/>
</svg>

Before

Width:  |  Height:  |  Size: 493 B

View File

@ -1,12 +0,0 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555643 0.555643 0 1.24111 0H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79675 39.5036 2.48221L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
<path d="M38.7589 0H35.0356C35.721 0 36.2767 0.555643 36.2767 1.24111V38.7589C36.2767 39.4444 35.721 40 35.0356 40H38.7589C39.4444 40 40 39.4444 40 38.7589V1.24111C40 0.555643 39.4444 0 38.7589 0Z" fill="#D1D1D1"/>
<path opacity="0.6" d="M8.64062 31.8319V33.3213C8.64062 34.0067 8.22091 34.5624 7.70312 34.5624H3.57813C3.06034 34.5624 2.64062 34.0067 2.64062 33.3213V31.8319C2.64062 31.1465 3.06034 30.5908 3.57813 30.5908H7.70312C8.22091 30.5908 8.64062 31.1465 8.64062 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M8.64062 7.24111V8.73044C8.64062 9.4159 8.22091 9.97154 7.70312 9.97154H3.57813C3.06034 9.97154 2.64062 9.4159 2.64062 8.73044V7.24111C2.64062 6.55565 3.06034 6 3.57813 6H7.70312C8.22091 6 8.64062 6.55565 8.64062 7.24111Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M27.6406 31.8319V33.3213C27.6406 34.0067 28.0603 34.5624 28.5781 34.5624H32.7031C33.2209 34.5624 33.6406 34.0067 33.6406 33.3213V31.8319C33.6406 31.1465 33.2209 30.5908 32.7031 30.5908H28.5781C28.0603 30.5908 27.6406 31.1465 27.6406 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M27.6406 7.24111V8.73044C27.6406 9.4159 28.0603 9.97154 28.5781 9.97154H32.7031C33.2209 9.97154 33.6406 9.4159 33.6406 8.73044V7.24111C33.6406 6.55565 33.2209 6 32.7031 6H28.5781C28.0603 6 27.6406 6.55565 27.6406 7.24111Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M15.0625 31.8319V33.3213C15.0625 34.0067 15.4822 34.5624 16 34.5624H20.125C20.6428 34.5624 21.0625 34.0067 21.0625 33.3213V31.8319C21.0625 31.1465 20.6428 30.5908 20.125 30.5908H16C15.4822 30.5908 15.0625 31.1465 15.0625 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M15.0625 7.24111V8.73044C15.0625 9.4159 15.4822 9.97154 16 9.97154H20.125C20.6428 9.97154 21.0625 9.4159 21.0625 8.73044V7.24111C21.0625 6.55565 20.6428 6 20.125 6H16C15.4822 6 15.0625 6.55565 15.0625 7.24111Z" fill="#023DFE" fill-opacity="0.5"/>
<path d="M23.125 0H24.9867V40H23.125V0Z" fill="#D1D1D1"/>
<path d="M11.1719 0H13.0335V40H11.1719V0Z" fill="#D1D1D1"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,34 +0,0 @@
<svg width="52" height="48" viewBox="0 0 52 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_4487_7074)">
<path d="M4 5.53846C4 4.68879 4.69121 4 5.54386 4H46.4561C47.3088 4 48 4.68879 48 5.53846V42.4615C48 43.3112 47.3088 44 46.4561 44H5.54386C4.69121 44 4 43.3112 4 42.4615V5.53846Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.4561 4.15385H5.54386C4.77647 4.15385 4.15439 4.77376 4.15439 5.53846V42.4615C4.15439 43.2262 4.77647 43.8462 5.54386 43.8462H46.4561C47.2235 43.8462 47.8456 43.2262 47.8456 42.4615V5.53846C47.8456 4.77376 47.2235 4.15385 46.4561 4.15385ZM5.54386 4C4.69121 4 4 4.68879 4 5.53846V42.4615C4 43.3112 4.69121 44 5.54386 44H46.4561C47.3088 44 48 43.3112 48 42.4615V5.53846C48 4.68879 47.3088 4 46.4561 4H5.54386Z" fill="#E4E4E4"/>
<path d="M12.6144 10.6736C12.6148 10.6994 12.6228 10.7245 12.6374 10.7458C12.6519 10.7671 12.6724 10.7838 12.6963 10.7937C12.91 10.8873 13.0907 11.0425 13.2152 11.2393C13.3397 11.4361 13.4024 11.6655 13.3951 11.898C13.3901 12.2075 13.2619 12.5023 13.0387 12.7176C12.8155 12.9329 12.5157 13.051 12.2051 13.046C11.8945 13.041 11.5986 12.9132 11.3826 12.6908C11.1665 12.4684 11.048 12.1696 11.053 11.8601C11.0533 11.634 11.1195 11.4129 11.2436 11.2236C11.3677 11.0343 11.5443 10.8849 11.7519 10.7938C11.7758 10.7838 11.7963 10.7672 11.8108 10.7458C11.8254 10.7244 11.8333 10.6993 11.8337 10.6735C11.8338 10.6522 11.8286 10.6313 11.8186 10.6125C11.8086 10.5938 11.7942 10.5777 11.7765 10.5658C11.7588 10.5539 11.7385 10.5466 11.7173 10.5443C11.6961 10.5421 11.6747 10.5451 11.655 10.553C11.353 10.6835 11.1054 10.9136 10.9538 11.2048C10.8022 11.4959 10.756 11.8302 10.8228 12.1513C10.8897 12.4724 11.0656 12.7608 11.3208 12.9678C11.5761 13.1748 11.8952 13.2879 12.2243 13.2879C12.5534 13.2879 12.8725 13.1748 13.1277 12.9678C13.383 12.7608 13.5589 12.4724 13.6257 12.1513C13.6926 11.8302 13.6463 11.4959 13.4948 11.2048C13.3432 10.9136 13.0956 10.6835 12.7936 10.553C12.7738 10.545 12.7523 10.5419 12.7311 10.5441C12.7098 10.5463 12.6894 10.5537 12.6717 10.5656C12.654 10.5776 12.6395 10.5936 12.6295 10.6125C12.6195 10.6313 12.6144 10.6523 12.6144 10.6736Z" fill="#6488FB"/>
<path d="M12.3542 10.3042C12.3542 10.2326 12.2959 10.1746 12.2241 10.1746C12.1522 10.1746 12.094 10.2326 12.094 10.3042V11.0822C12.094 11.1538 12.1522 11.2119 12.2241 11.2119C12.2959 11.2119 12.3542 11.1538 12.3542 11.0822V10.3042Z" fill="#6488FB"/>
<path d="M12.6144 35.1144C12.6148 35.1402 12.6228 35.1653 12.6374 35.1866C12.6519 35.2079 12.6724 35.2246 12.6963 35.2345C12.91 35.3281 13.0907 35.4833 13.2152 35.6801C13.3397 35.8769 13.4024 36.1063 13.3951 36.3388C13.3901 36.6483 13.2619 36.9431 13.0387 37.1584C12.8155 37.3737 12.5157 37.4918 12.2051 37.4868C11.8945 37.4818 11.5986 37.354 11.3826 37.1316C11.1665 36.9092 11.048 36.6104 11.053 36.3009C11.0533 36.0748 11.1195 35.8537 11.2436 35.6644C11.3677 35.4751 11.5443 35.3258 11.7519 35.2346C11.7758 35.2246 11.7963 35.208 11.8108 35.1866C11.8254 35.1652 11.8333 35.1401 11.8337 35.1143C11.8338 35.093 11.8286 35.0721 11.8186 35.0533C11.8086 35.0346 11.7942 35.0185 11.7765 35.0066C11.7588 34.9947 11.7385 34.9874 11.7173 34.9851C11.6961 34.9829 11.6747 34.9859 11.655 34.9938C11.353 35.1243 11.1054 35.3544 10.9538 35.6456C10.8022 35.9367 10.756 36.271 10.8228 36.5921C10.8897 36.9132 11.0656 37.2016 11.3208 37.4086C11.5761 37.6156 11.8952 37.7287 12.2243 37.7287C12.5534 37.7287 12.8725 37.6156 13.1277 37.4086C13.383 37.2016 13.5589 36.9132 13.6257 36.5921C13.6926 36.271 13.6463 35.9367 13.4948 35.6456C13.3432 35.3544 13.0956 35.1243 12.7936 34.9938C12.7738 34.9858 12.7523 34.9827 12.7311 34.9849C12.7098 34.9871 12.6894 34.9945 12.6717 35.0064C12.654 35.0184 12.6395 35.0345 12.6295 35.0533C12.6195 35.0721 12.6144 35.0931 12.6144 35.1144Z" fill="#6488FB"/>
<path d="M12.3542 34.745C12.3542 34.6734 12.2959 34.6154 12.2241 34.6154C12.1522 34.6154 12.094 34.6734 12.094 34.745V35.523C12.094 35.5946 12.1522 35.6527 12.2241 35.6527C12.2959 35.6527 12.3542 35.5946 12.3542 35.523V34.745Z" fill="#6488FB"/>
<path d="M41.4846 10.6736C41.485 10.6994 41.493 10.7245 41.5075 10.7458C41.5221 10.7671 41.5426 10.7838 41.5665 10.7937C41.7801 10.8873 41.9608 11.0425 42.0854 11.2393C42.2099 11.4361 42.2726 11.6655 42.2653 11.898C42.2603 12.2075 42.1321 12.5023 41.9089 12.7176C41.6857 12.9329 41.3858 13.051 41.0753 13.046C40.7647 13.041 40.4688 12.9132 40.2528 12.6908C40.0367 12.4684 39.9182 12.1696 39.9232 11.8601C39.9235 11.634 39.9897 11.4129 40.1138 11.2236C40.2379 11.0343 40.4144 10.8849 40.6221 10.7938C40.646 10.7838 40.6665 10.7672 40.681 10.7458C40.6955 10.7244 40.7035 10.6993 40.7039 10.6735C40.7039 10.6522 40.6987 10.6313 40.6888 10.6125C40.6788 10.5938 40.6643 10.5777 40.6467 10.5658C40.629 10.5539 40.6087 10.5466 40.5875 10.5443C40.5663 10.5421 40.5449 10.5451 40.5251 10.553C40.2232 10.6835 39.9756 10.9136 39.824 11.2048C39.6724 11.4959 39.6262 11.8302 39.693 12.1513C39.7599 12.4724 39.9357 12.7608 40.191 12.9678C40.4463 13.1748 40.7653 13.2879 41.0945 13.2879C41.4236 13.2879 41.7426 13.1748 41.9979 12.9678C42.2532 12.7608 42.4291 12.4724 42.4959 12.1513C42.5628 11.8302 42.5165 11.4959 42.3649 11.2048C42.2134 10.9136 41.9657 10.6835 41.6638 10.553C41.644 10.545 41.6225 10.5419 41.6013 10.5441C41.58 10.5463 41.5596 10.5537 41.5419 10.5656C41.5242 10.5776 41.5097 10.5936 41.4997 10.6125C41.4897 10.6313 41.4845 10.6523 41.4846 10.6736Z" fill="#6488FB"/>
<path d="M41.2244 10.3042C41.2244 10.2326 41.1661 10.1746 41.0943 10.1746C41.0224 10.1746 40.9641 10.2326 40.9641 10.3042V11.0822C40.9641 11.1538 41.0224 11.2119 41.0943 11.2119C41.1661 11.2119 41.2244 11.1538 41.2244 11.0822V10.3042Z" fill="#6488FB"/>
<path d="M26.3548 10.6736C26.3552 10.6994 26.3632 10.7245 26.3777 10.7458C26.3922 10.7671 26.4127 10.7838 26.4366 10.7937C26.6503 10.8873 26.831 11.0425 26.9555 11.2393C27.0801 11.4361 27.1427 11.6655 27.1355 11.898C27.1305 12.2075 27.0022 12.5023 26.7791 12.7176C26.5559 12.9329 26.256 13.051 25.9454 13.046C25.6349 13.041 25.339 12.9132 25.1229 12.6908C24.9069 12.4684 24.7884 12.1696 24.7934 11.8601C24.7937 11.634 24.8599 11.4129 24.984 11.2236C25.108 11.0343 25.2846 10.8849 25.4922 10.7938C25.5162 10.7838 25.5366 10.7672 25.5512 10.7458C25.5657 10.7244 25.5737 10.6993 25.5741 10.6735C25.5741 10.6522 25.5689 10.6313 25.5589 10.6125C25.549 10.5938 25.5345 10.5777 25.5169 10.5658C25.4992 10.5539 25.4789 10.5466 25.4577 10.5443C25.4365 10.5421 25.4151 10.5451 25.3953 10.553C25.0933 10.6835 24.8457 10.9136 24.6942 11.2048C24.5426 11.4959 24.4963 11.8302 24.5632 12.1513C24.63 12.4724 24.8059 12.7608 25.0612 12.9678C25.3164 13.1748 25.6355 13.2879 25.9646 13.2879C26.2938 13.2879 26.6128 13.1748 26.8681 12.9678C27.1234 12.7608 27.2992 12.4724 27.3661 12.1513C27.4329 11.8302 27.3867 11.4959 27.2351 11.2048C27.0835 10.9136 26.8359 10.6835 26.534 10.553C26.5142 10.545 26.4927 10.5419 26.4714 10.5441C26.4502 10.5463 26.4298 10.5537 26.4121 10.5656C26.3944 10.5776 26.3799 10.5936 26.3699 10.6125C26.3599 10.6313 26.3547 10.6523 26.3548 10.6736Z" fill="#6488FB"/>
<path d="M26.0945 10.3042C26.0945 10.2326 26.0363 10.1746 25.9644 10.1746C25.8926 10.1746 25.8343 10.2326 25.8343 10.3042V11.0822C25.8343 11.1538 25.8926 11.2119 25.9644 11.2119C26.0363 11.2119 26.0945 11.1538 26.0945 11.0822V10.3042Z" fill="#6488FB"/>
<path d="M41.4846 35.1144C41.485 35.1402 41.493 35.1653 41.5075 35.1866C41.5221 35.2079 41.5426 35.2246 41.5665 35.2345C41.7801 35.3281 41.9608 35.4833 42.0854 35.6801C42.2099 35.8769 42.2726 36.1063 42.2653 36.3388C42.2603 36.6483 42.1321 36.9431 41.9089 37.1584C41.6857 37.3737 41.3858 37.4918 41.0753 37.4868C40.7647 37.4818 40.4688 37.354 40.2528 37.1316C40.0367 36.9092 39.9182 36.6104 39.9232 36.3009C39.9235 36.0748 39.9897 35.8537 40.1138 35.6644C40.2379 35.4751 40.4144 35.3258 40.6221 35.2346C40.646 35.2246 40.6665 35.208 40.681 35.1866C40.6955 35.1652 40.7035 35.1401 40.7039 35.1143C40.7039 35.093 40.6987 35.0721 40.6888 35.0533C40.6788 35.0346 40.6643 35.0185 40.6467 35.0066C40.629 34.9947 40.6087 34.9874 40.5875 34.9851C40.5663 34.9829 40.5449 34.9859 40.5251 34.9938C40.2232 35.1243 39.9756 35.3544 39.824 35.6456C39.6724 35.9367 39.6262 36.271 39.693 36.5921C39.7599 36.9132 39.9357 37.2016 40.191 37.4086C40.4463 37.6156 40.7653 37.7287 41.0945 37.7287C41.4236 37.7287 41.7426 37.6156 41.9979 37.4086C42.2532 37.2016 42.4291 36.9132 42.4959 36.5921C42.5628 36.271 42.5165 35.9367 42.3649 35.6456C42.2134 35.3544 41.9657 35.1243 41.6638 34.9938C41.644 34.9858 41.6225 34.9827 41.6013 34.9849C41.58 34.9871 41.5596 34.9945 41.5419 35.0064C41.5242 35.0184 41.5097 35.0345 41.4997 35.0533C41.4897 35.0721 41.4845 35.0931 41.4846 35.1144Z" fill="#6488FB"/>
<path d="M41.2244 34.745C41.2244 34.6734 41.1661 34.6154 41.0943 34.6154C41.0224 34.6154 40.9641 34.6734 40.9641 34.745V35.523C40.9641 35.5946 41.0224 35.6527 41.0943 35.6527C41.1661 35.6527 41.2244 35.5946 41.2244 35.523V34.745Z" fill="#6488FB"/>
<path d="M26.3548 35.1144C26.3552 35.1402 26.3632 35.1653 26.3777 35.1866C26.3922 35.2079 26.4127 35.2246 26.4366 35.2345C26.6503 35.3281 26.831 35.4833 26.9555 35.6801C27.0801 35.8769 27.1427 36.1063 27.1355 36.3388C27.1305 36.6483 27.0022 36.9431 26.7791 37.1584C26.5559 37.3737 26.256 37.4918 25.9454 37.4868C25.6349 37.4818 25.339 37.354 25.1229 37.1316C24.9069 36.9092 24.7884 36.6104 24.7934 36.3009C24.7937 36.0748 24.8599 35.8537 24.984 35.6644C25.108 35.4751 25.2846 35.3258 25.4922 35.2346C25.5162 35.2246 25.5366 35.208 25.5512 35.1866C25.5657 35.1652 25.5737 35.1401 25.5741 35.1143C25.5741 35.093 25.5689 35.0721 25.5589 35.0533C25.549 35.0346 25.5345 35.0185 25.5169 35.0066C25.4992 34.9947 25.4789 34.9874 25.4577 34.9851C25.4365 34.9829 25.4151 34.9859 25.3953 34.9938C25.0933 35.1243 24.8457 35.3544 24.6942 35.6456C24.5426 35.9367 24.4963 36.271 24.5632 36.5921C24.63 36.9132 24.8059 37.2016 25.0612 37.4086C25.3164 37.6156 25.6355 37.7287 25.9646 37.7287C26.2938 37.7287 26.6128 37.6156 26.8681 37.4086C27.1234 37.2016 27.2992 36.9132 27.3661 36.5921C27.4329 36.271 27.3867 35.9367 27.2351 35.6456C27.0835 35.3544 26.8359 35.1243 26.534 34.9938C26.5142 34.9858 26.4927 34.9827 26.4714 34.9849C26.4502 34.9871 26.4298 34.9945 26.4121 35.0064C26.3944 35.0184 26.3799 35.0345 26.3699 35.0533C26.3599 35.0721 26.3547 35.0931 26.3548 35.1144Z" fill="#6488FB"/>
<path d="M26.0945 34.745C26.0945 34.6734 26.0363 34.6154 25.9644 34.6154C25.8926 34.6154 25.8343 34.6734 25.8343 34.745V35.523C25.8343 35.5946 25.8926 35.6527 25.9644 35.6527C26.0363 35.6527 26.0945 35.5946 26.0945 35.523V34.745Z" fill="#6488FB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.92631 41.8462L4.92632 5.38462H5.0807L5.0807 41.8462H4.92631Z" fill="#D3D1D1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.9193 41.8462V5.38462H47.0737V41.8462H46.9193Z" fill="#D3D1D1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.6667 43.8462V4.15385H18.8211V43.8462H18.6667Z" fill="#E4E4E4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.3333 43.8462V4.15385H33.4877V43.8462H33.3333Z" fill="#E4E4E4"/>
</g>
<defs>
<filter id="filter0_d_4487_7074" x="0" y="0" width="52" height="48" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4487_7074"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4487_7074" result="shape"/>
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -1,4 +0,0 @@
<svg width="19" height="21" viewBox="0 0 19 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.7981 3.37822C11.8007 3.54583 11.8523 3.709 11.9465 3.84766C12.0407 3.98632 12.1734 4.09442 12.3282 4.15866C13.7123 4.76765 14.8827 5.77642 15.6893 7.05545C16.4959 8.33448 16.9018 9.8254 16.8549 11.3368C16.8223 13.3485 15.9918 15.2649 14.5462 16.6643C13.1006 18.0637 11.1584 18.8316 9.14663 18.799C7.13491 18.7663 5.21855 17.9359 3.81912 16.4903C2.41969 15.0447 1.65184 13.1024 1.68447 11.0907C1.68642 9.62104 2.11527 8.1836 2.91888 6.95311C3.7225 5.72263 4.86627 4.7521 6.21116 4.1595C6.36606 4.09488 6.49873 3.98645 6.59289 3.84752C6.68706 3.70859 6.73863 3.5452 6.74128 3.37738C6.7415 3.23934 6.7078 3.10335 6.64316 2.98138C6.57852 2.85941 6.4849 2.75519 6.37055 2.67787C6.25619 2.60055 6.12459 2.5525 5.98732 2.53795C5.85004 2.5234 5.7113 2.54279 5.58327 2.59442C3.62737 3.44239 2.02347 4.93853 1.04172 6.83083C0.0599786 8.72313 -0.239618 10.896 0.193397 12.9833C0.626412 15.0707 1.76558 16.9451 3.41902 18.2907C5.07246 19.6364 7.13914 20.3711 9.27095 20.3711C11.4028 20.3711 13.4694 19.6364 15.1229 18.2907C16.7763 16.9451 17.9155 15.0707 18.3485 12.9833C18.7815 10.896 18.4819 8.72313 17.5002 6.83083C16.5184 4.93853 14.9145 3.44239 12.9586 2.59442C12.8304 2.54223 12.6913 2.52242 12.5536 2.53676C12.4159 2.55109 12.2839 2.59912 12.1692 2.6766C12.0545 2.75408 11.9606 2.85862 11.8959 2.98099C11.8311 3.10336 11.7976 3.23979 11.7981 3.37822Z" fill="#C0B4B4"/>
<path d="M10.1124 0.977567C10.1124 0.512101 9.73503 0.134766 9.26956 0.134766C8.80409 0.134766 8.42676 0.512101 8.42676 0.977567V6.03437C8.42676 6.49984 8.80409 6.87717 9.26956 6.87717C9.73503 6.87717 10.1124 6.49984 10.1124 6.03437V0.977567Z" fill="#C0B4B4"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,4 +0,0 @@
<svg width="19" height="21" viewBox="0 0 19 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.7981 3.37822C11.8007 3.54583 11.8523 3.709 11.9465 3.84766C12.0407 3.98632 12.1734 4.09442 12.3282 4.15866C13.7123 4.76765 14.8827 5.77642 15.6893 7.05545C16.4959 8.33448 16.9018 9.8254 16.8549 11.3368C16.8223 13.3485 15.9918 15.2649 14.5462 16.6643C13.1006 18.0637 11.1584 18.8316 9.14663 18.799C7.13491 18.7663 5.21855 17.9359 3.81912 16.4903C2.41969 15.0447 1.65184 13.1024 1.68447 11.0907C1.68642 9.62104 2.11527 8.1836 2.91888 6.95311C3.7225 5.72263 4.86627 4.7521 6.21116 4.1595C6.36606 4.09488 6.49873 3.98645 6.59289 3.84752C6.68706 3.70859 6.73863 3.5452 6.74128 3.37738C6.7415 3.23934 6.7078 3.10335 6.64316 2.98138C6.57852 2.85941 6.4849 2.75519 6.37055 2.67787C6.25619 2.60055 6.12459 2.5525 5.98732 2.53795C5.85004 2.5234 5.7113 2.54279 5.58327 2.59442C3.62737 3.44239 2.02347 4.93853 1.04172 6.83083C0.0599786 8.72313 -0.239618 10.896 0.193397 12.9833C0.626412 15.0707 1.76558 16.9451 3.41902 18.2907C5.07246 19.6364 7.13914 20.3711 9.27095 20.3711C11.4028 20.3711 13.4694 19.6364 15.1229 18.2907C16.7763 16.9451 17.9155 15.0707 18.3485 12.9833C18.7815 10.896 18.4819 8.72313 17.5002 6.83083C16.5184 4.93853 14.9145 3.44239 12.9586 2.59442C12.8304 2.54223 12.6913 2.52242 12.5536 2.53676C12.4159 2.55109 12.2839 2.59912 12.1692 2.6766C12.0545 2.75408 11.9606 2.85862 11.8959 2.98099C11.8311 3.10336 11.7976 3.23979 11.7981 3.37822Z" fill="#6488FB"/>
<path d="M10.1124 0.977567C10.1124 0.512101 9.73503 0.134766 9.26956 0.134766C8.80409 0.134766 8.42676 0.512101 8.42676 0.977567V6.03437C8.42676 6.49984 8.80409 6.87717 9.26956 6.87717C9.73503 6.87717 10.1124 6.49984 10.1124 6.03437V0.977567Z" fill="#6488FB"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,3 +0,0 @@
<svg width="11" height="14" viewBox="0 0 11 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 3.64L7.27 7L2 10.36V3.64ZM0 0V14L11 7L0 0Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 174 B

View File

@ -10,12 +10,12 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
611C662010675536F855E5CA /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 490AAF90B8FBFCC5BA996845 /* Pods_RunnerTests.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
964EC64D4BABF3375BEBF6DE /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB51EC18BE9E4FD7A688D262 /* Pods_RunnerTests.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
CE9CA504D8FF2965F977B16B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 274C82CD6955A1499B0B1ECC /* Pods_Runner.framework */; };
D31283674D2826D7EF8E56BC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25B37F5982CD6994FABA2CC1 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -42,20 +42,24 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
064BE0B8B723A6E30728B215 /* Pods-RunnerTests.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-prod.xcconfig"; sourceTree = "<group>"; };
0D60D6C4BBD804473BD9E4A0 /* Pods-RunnerTests.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-prod.xcconfig"; sourceTree = "<group>"; };
01BAAF935356ECBDD35AF0DB /* Pods-RunnerTests.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-prod.xcconfig"; sourceTree = "<group>"; };
12AD49A621BEBB053FD06115 /* Pods-Runner.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-prod.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2688A8D4C03F1C4585B3EFE2 /* Pods-Runner.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-dev.xcconfig"; sourceTree = "<group>"; };
274C82CD6955A1499B0B1ECC /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1F99043C7AC9BDABD8A4D41A /* Pods-Runner.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-dev.xcconfig"; sourceTree = "<group>"; };
210827A693936E5201C5E75C /* Pods-RunnerTests.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-dev.xcconfig"; sourceTree = "<group>"; };
238CAAD9FFF9A0C9ED3CFAB2 /* Pods-RunnerTests.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-prod.xcconfig"; sourceTree = "<group>"; };
25B37F5982CD6994FABA2CC1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4F6A2F89436864C7EE769652 /* Pods-RunnerTests.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-dev.xcconfig"; sourceTree = "<group>"; };
54B9D4926B53AAFC49A54F19 /* Pods-Runner.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-prod.xcconfig"; sourceTree = "<group>"; };
444D77D28A8CDF32047CD0AF /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
490AAF90B8FBFCC5BA996845 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5DE3E6D1EADE3D3859FC1B69 /* Pods-Runner.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-dev.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
949637473C534E1F68B19CC0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -63,14 +67,16 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9D1B204BC7CD29434FE9D537 /* Pods-Runner.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-dev.xcconfig"; sourceTree = "<group>"; };
C33EAABFBF3F560A8EFB0BC0 /* Pods-RunnerTests.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-dev.xcconfig"; sourceTree = "<group>"; };
E0A467016A4C6B17ECA05534 /* Pods-Runner.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-prod.xcconfig"; sourceTree = "<group>"; };
E2512B7B8C737577EB9DB570 /* Pods-RunnerTests.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-dev.xcconfig"; sourceTree = "<group>"; };
F5E8A17F8AB7D50983179FD3 /* Pods-Runner.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-dev.xcconfig"; sourceTree = "<group>"; };
FA2359C69B2F150BE9833D5A /* Pods-RunnerTests.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-prod.xcconfig"; sourceTree = "<group>"; };
FB51EC18BE9E4FD7A688D262 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
FC3EFA91747319965EF91609 /* Pods-Runner.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-prod.xcconfig"; sourceTree = "<group>"; };
9B82456986D7FA25420A224F /* Pods-Runner.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-prod.xcconfig"; sourceTree = "<group>"; };
A3D4DF5D9888DAC25E2380AA /* Pods-RunnerTests.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-dev.xcconfig"; sourceTree = "<group>"; };
AAC9129FD50E64509AD1B9AF /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
BFD4DDED98208034B60B5311 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
C41134CD2FDFC1A2BDF49283 /* Pods-Runner.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-dev.xcconfig"; sourceTree = "<group>"; };
C5DBBF9417E4F8A9A08DFF02 /* Pods-RunnerTests.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-prod.xcconfig"; sourceTree = "<group>"; };
D0F6245A5BF345FCC425515C /* Pods-Runner.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-prod.xcconfig"; sourceTree = "<group>"; };
DFB6BB492A265F2BF6FDC8C0 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
EE971EFEA60AEDFDB361D9A3 /* Pods-RunnerTests.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-dev.xcconfig"; sourceTree = "<group>"; };
F323D632CA976B68DDB0E669 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -78,7 +84,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CE9CA504D8FF2965F977B16B /* Pods_Runner.framework in Frameworks */,
D31283674D2826D7EF8E56BC /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -86,7 +92,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
964EC64D4BABF3375BEBF6DE /* Pods_RunnerTests.framework in Frameworks */,
611C662010675536F855E5CA /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -96,18 +102,24 @@
2F70EB4341A83C900EB253DC /* Pods */ = {
isa = PBXGroup;
children = (
FC3EFA91747319965EF91609 /* Pods-Runner.debug-prod.xcconfig */,
F5E8A17F8AB7D50983179FD3 /* Pods-Runner.debug-dev.xcconfig */,
54B9D4926B53AAFC49A54F19 /* Pods-Runner.release-prod.xcconfig */,
2688A8D4C03F1C4585B3EFE2 /* Pods-Runner.release-dev.xcconfig */,
E0A467016A4C6B17ECA05534 /* Pods-Runner.profile-prod.xcconfig */,
9D1B204BC7CD29434FE9D537 /* Pods-Runner.profile-dev.xcconfig */,
FA2359C69B2F150BE9833D5A /* Pods-RunnerTests.debug-prod.xcconfig */,
E2512B7B8C737577EB9DB570 /* Pods-RunnerTests.debug-dev.xcconfig */,
064BE0B8B723A6E30728B215 /* Pods-RunnerTests.release-prod.xcconfig */,
C33EAABFBF3F560A8EFB0BC0 /* Pods-RunnerTests.release-dev.xcconfig */,
0D60D6C4BBD804473BD9E4A0 /* Pods-RunnerTests.profile-prod.xcconfig */,
4F6A2F89436864C7EE769652 /* Pods-RunnerTests.profile-dev.xcconfig */,
BFD4DDED98208034B60B5311 /* Pods-Runner.debug.xcconfig */,
949637473C534E1F68B19CC0 /* Pods-Runner.release.xcconfig */,
444D77D28A8CDF32047CD0AF /* Pods-Runner.profile.xcconfig */,
DFB6BB492A265F2BF6FDC8C0 /* Pods-RunnerTests.debug.xcconfig */,
F323D632CA976B68DDB0E669 /* Pods-RunnerTests.release.xcconfig */,
AAC9129FD50E64509AD1B9AF /* Pods-RunnerTests.profile.xcconfig */,
9B82456986D7FA25420A224F /* Pods-Runner.debug-prod.xcconfig */,
5DE3E6D1EADE3D3859FC1B69 /* Pods-Runner.debug-dev.xcconfig */,
12AD49A621BEBB053FD06115 /* Pods-Runner.release-prod.xcconfig */,
C41134CD2FDFC1A2BDF49283 /* Pods-Runner.release-dev.xcconfig */,
D0F6245A5BF345FCC425515C /* Pods-Runner.profile-prod.xcconfig */,
1F99043C7AC9BDABD8A4D41A /* Pods-Runner.profile-dev.xcconfig */,
01BAAF935356ECBDD35AF0DB /* Pods-RunnerTests.debug-prod.xcconfig */,
EE971EFEA60AEDFDB361D9A3 /* Pods-RunnerTests.debug-dev.xcconfig */,
C5DBBF9417E4F8A9A08DFF02 /* Pods-RunnerTests.release-prod.xcconfig */,
A3D4DF5D9888DAC25E2380AA /* Pods-RunnerTests.release-dev.xcconfig */,
238CAAD9FFF9A0C9ED3CFAB2 /* Pods-RunnerTests.profile-prod.xcconfig */,
210827A693936E5201C5E75C /* Pods-RunnerTests.profile-dev.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -120,11 +132,11 @@
path = RunnerTests;
sourceTree = "<group>";
};
61B46FA3FB0932D29E3C6E47 /* Frameworks */ = {
876D3217A8BBDAF41961161F /* Frameworks */ = {
isa = PBXGroup;
children = (
274C82CD6955A1499B0B1ECC /* Pods_Runner.framework */,
FB51EC18BE9E4FD7A688D262 /* Pods_RunnerTests.framework */,
25B37F5982CD6994FABA2CC1 /* Pods_Runner.framework */,
490AAF90B8FBFCC5BA996845 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -148,7 +160,7 @@
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
2F70EB4341A83C900EB253DC /* Pods */,
61B46FA3FB0932D29E3C6E47 /* Frameworks */,
876D3217A8BBDAF41961161F /* Frameworks */,
);
sourceTree = "<group>";
};
@ -183,7 +195,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
73698F4EABFF3F9B7ADF4220 /* [CP] Check Pods Manifest.lock */,
3B971DE531245D7FD2921C30 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
C2B33A7265AF659D80692473 /* Frameworks */,
@ -202,7 +214,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
BF71A0E0099ADA10FE9B580A /* [CP] Check Pods Manifest.lock */,
3DC878D0674AA34AEC9695FB /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
B07E4A152C9B8EA4001F6910 /* copy GoogleService.plist file to the correct location */,
97C146EA1CF9000F007C117D /* Sources */,
@ -210,9 +222,9 @@
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
315A05630CF83C532DBBCBF2 /* [CP] Embed Pods Frameworks */,
3724F7A126D8469D5B04D144 /* [CP] Copy Pods Resources */,
4768286A3BADB12BBB8C6996 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
6CF71F42A45B39E9945C8410 /* [CP] Embed Pods Frameworks */,
14DF593CA13D27D3781140F6 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -284,7 +296,24 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
14DF593CA13D27D3781140F6 /* [CP] Copy Pods Resources */ = {
315A05630CF83C532DBBCBF2 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3724F7A126D8469D5B04D144 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -317,42 +346,7 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
4768286A3BADB12BBB8C6996 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\n#!/bin/bash\nPATH=${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=$PODS_ROOT/FirebaseCrashlytics/upload-symbols --platform=ios --apple-project-path=${SRCROOT} --env-platform-name=${PLATFORM_NAME} --env-configuration=${CONFIGURATION} --env-project-dir=${PROJECT_DIR} --env-built-products-dir=${BUILT_PRODUCTS_DIR} --env-dwarf-dsym-folder-path=${DWARF_DSYM_FOLDER_PATH} --env-dwarf-dsym-file-name=${DWARF_DSYM_FILE_NAME} --env-infoplist-path=${INFOPLIST_PATH} --default-config=default\n";
};
6CF71F42A45B39E9945C8410 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
73698F4EABFF3F9B7ADF4220 /* [CP] Check Pods Manifest.lock */ = {
3B971DE531245D7FD2921C30 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -374,6 +368,46 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3DC878D0674AA34AEC9695FB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
4768286A3BADB12BBB8C6996 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\n#!/bin/bash\nPATH=${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=$PODS_ROOT/FirebaseCrashlytics/upload-symbols --platform=ios --apple-project-path=${SRCROOT} --env-platform-name=${PLATFORM_NAME} --env-configuration=${CONFIGURATION} --env-project-dir=${PROJECT_DIR} --env-built-products-dir=${BUILT_PRODUCTS_DIR} --env-dwarf-dsym-folder-path=${DWARF_DSYM_FOLDER_PATH} --env-dwarf-dsym-file-name=${DWARF_DSYM_FILE_NAME} --env-infoplist-path=${INFOPLIST_PATH} --default-config=default\n";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@ -407,28 +441,6 @@
shellPath = /bin/sh;
shellScript = "# Get a reference to the destination location for the GoogleService-Info.plist\n# This is the default location where Firebase init code expects to find GoogleServices-Info.plist file.\nPLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app\n# We have named our Build Configurations as Debug-dev, Debug-prod etc.\n# Here, dev and prod are the scheme names. This kind of naming is required by Flutter for flavors to work.\n# We are using the $CONFIGURATION variable available in the XCode build environment to get the build configuration.\nif [ \"${CONFIGURATION}\" == \"Debug-prod\" ] || [ \"${CONFIGURATION}\" == \"Release-prod\" ] || [ \"${CONFIGURATION}\" == \"Profile-prod\" ] || [ \"${CONFIGURATION}\" == \"Release\" ]; then\ncp \"${PROJECT_DIR}/config/prod/GoogleService-Info.plist\" \"${PLIST_DESTINATION}/GoogleService-Info.plist\"\necho \"Production plist copied\"\nelif [ \"${CONFIGURATION}\" == \"Debug-dev\" ] || [ \"${CONFIGURATION}\" == \"Release-dev\" ] || [ \"${CONFIGURATION}\" == \"Profile-dev\" ] || [ \"${CONFIGURATION}\" == \"Debug\" ]; then\ncp \"${PROJECT_DIR}/config/dev/GoogleService-Info.plist\" \"${PLIST_DESTINATION}/GoogleService-Info.plist\"\necho \"Development plist copied\"\nfi\n";
};
BF71A0E0099ADA10FE9B580A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -563,7 +575,7 @@
};
331C8088294A63A400263BE5 /* Debug-prod */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FA2359C69B2F150BE9833D5A /* Pods-RunnerTests.debug-prod.xcconfig */;
baseConfigurationReference = 01BAAF935356ECBDD35AF0DB /* Pods-RunnerTests.debug-prod.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@ -581,7 +593,7 @@
};
331C8089294A63A400263BE5 /* Release-prod */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 064BE0B8B723A6E30728B215 /* Pods-RunnerTests.release-prod.xcconfig */;
baseConfigurationReference = C5DBBF9417E4F8A9A08DFF02 /* Pods-RunnerTests.release-prod.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@ -597,7 +609,7 @@
};
331C808A294A63A400263BE5 /* Profile-prod */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 0D60D6C4BBD804473BD9E4A0 /* Pods-RunnerTests.profile-prod.xcconfig */;
baseConfigurationReference = 238CAAD9FFF9A0C9ED3CFAB2 /* Pods-RunnerTests.profile-prod.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@ -873,7 +885,7 @@
};
B07E4A0E2C9B8C45001F6910 /* Debug-dev */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = E2512B7B8C737577EB9DB570 /* Pods-RunnerTests.debug-dev.xcconfig */;
baseConfigurationReference = EE971EFEA60AEDFDB361D9A3 /* Pods-RunnerTests.debug-dev.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@ -975,7 +987,7 @@
};
B07E4A112C9B8C52001F6910 /* Release-dev */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C33EAABFBF3F560A8EFB0BC0 /* Pods-RunnerTests.release-dev.xcconfig */;
baseConfigurationReference = A3D4DF5D9888DAC25E2380AA /* Pods-RunnerTests.release-dev.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@ -1073,7 +1085,7 @@
};
B07E4A142C9B8C5C001F6910 /* Profile-dev */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4F6A2F89436864C7EE769652 /* Pods-RunnerTests.profile-dev.xcconfig */;
baseConfigurationReference = 210827A693936E5201C5E75C /* Pods-RunnerTests.profile-dev.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;

View File

@ -34,7 +34,7 @@ part 'home_state.dart';
class HomeCubit extends Cubit<HomeState> {
HomeCubit._() : super(HomeInitial()) {
// checkIfNotificationPermissionGranted();
checkIfNotificationPermissionGranted();
fetchUserInfo();
if (selectedSpace == null) {
fetchUnitsByUserId();
@ -55,7 +55,7 @@ class HomeCubit extends Cubit<HomeState> {
Future fetchUserInfo() async {
try {
var uuid=await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
user = await ProfileApi().fetchUserInfo(uuid);
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
} catch (e) {
@ -76,12 +76,9 @@ class HomeCubit extends Cubit<HomeState> {
selectedSpace = null;
selectedRoom = null;
pageIndex = 0;
// OneSignal.User.pushSubscription
// .removeObserver((stateChanges) => oneSignalSubscriptionObserver);
// OneSignal.Notifications.removePermissionObserver(
// (permission) => oneSignalPermissionObserver);
// OneSignal.Notifications.removeClickListener(
// (event) => oneSignalClickListenerObserver);
OneSignal.User.pushSubscription.removeObserver((stateChanges) => oneSignalSubscriptionObserver);
OneSignal.Notifications.removePermissionObserver((permission) => oneSignalPermissionObserver);
OneSignal.Notifications.removeClickListener((event) => oneSignalClickListenerObserver);
return super.close();
}
@ -99,9 +96,9 @@ class HomeCubit extends Cubit<HomeState> {
var duration = const Duration(milliseconds: 300);
// void oneSignalPermissionObserver;
// void oneSignalSubscriptionObserver;
// void oneSignalClickListenerObserver;
void oneSignalPermissionObserver;
void oneSignalSubscriptionObserver;
void oneSignalClickListenerObserver;
// selectSpace(SpaceModel space) async {
// selectedSpace = space;
@ -123,36 +120,31 @@ class HomeCubit extends Cubit<HomeState> {
return;
}
var userUuid =
await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
'';
var userUuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? '';
if (userUuid.isNotEmpty) {
await OneSignal.login(userUuid);
}
//Enable push notifications
await OneSignal.User.pushSubscription.optIn();
// //this function will be called once a user is subscribed
// oneSignalSubscriptionObserver =
// OneSignal.User.pushSubscription.addObserver((state) async {
// if (state.current.optedIn) {
// await _sendSubscriptionId();
// }
// });
//this function will be called once a user is subscribed
oneSignalSubscriptionObserver = OneSignal.User.pushSubscription.addObserver((state) async {
if (state.current.optedIn) {
await _sendSubscriptionId();
}
});
// // Send the player id when a user allows notifications
// oneSignalPermissionObserver =
// OneSignal.Notifications.addPermissionObserver((state) async {
// await _sendSubscriptionId();
// });
// Send the player id when a user allows notifications
oneSignalPermissionObserver = OneSignal.Notifications.addPermissionObserver((state) async {
await _sendSubscriptionId();
});
// //check if the player id is sent, if not send it again
// await _sendSubscriptionId();
//check if the player id is sent, if not send it again
await _sendSubscriptionId();
// oneSignalClickListenerObserver =
// OneSignal.Notifications.addClickListener((event) async {
// //Once the user clicks on the notification
// });
oneSignalClickListenerObserver = OneSignal.Notifications.addClickListener((event) async {
//Once the user clicks on the notification
});
} catch (err) {
debugPrint("******* Error");
debugPrint(err.toString());
@ -221,8 +213,7 @@ class HomeCubit extends Cubit<HomeState> {
//////////////////////////////////////// API ////////////////////////////////////////
generateInvitation(SpaceModel unit) async {
try {
final invitationCode =
await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
final invitationCode = await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
if (invitationCode.isNotEmpty) {
Share.share('The invitation code is $invitationCode');
CustomSnackBar.displaySnackBar(
@ -238,9 +229,7 @@ class HomeCubit extends Cubit<HomeState> {
Future<bool> joinAUnit(String code) async {
try {
var userUuid =
await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
'';
var userUuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? '';
Map<String, String> body = {'inviteCode': code};
final success = await SpacesAPI.joinUnit(userUuid, body);
@ -276,8 +265,7 @@ class HomeCubit extends Cubit<HomeState> {
fetchRoomsByUnitId(SpaceModel space) async {
emitSafe(GetSpaceRoomsLoading());
try {
space.subspaces =
await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
space.subspaces = await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
} catch (failure) {
emitSafe(GetSpaceRoomsError(failure.toString()));
return;
@ -359,8 +347,7 @@ class HomeCubit extends Cubit<HomeState> {
size: 32,
),
style: ButtonStyle(
foregroundColor:
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {
Navigator.pushNamed(
@ -381,8 +368,7 @@ class HomeCubit extends Cubit<HomeState> {
NavigationService.navigatorKey.currentContext!
.read<SmartSceneSelectBloc>()
.add(const SmartSceneClearEvent());
BlocProvider.of<EffectPeriodBloc>(
NavigationService.navigatorKey.currentState!.context)
BlocProvider.of<EffectPeriodBloc>(NavigationService.navigatorKey.currentState!.context)
.add(ResetEffectivePeriod());
NavigationService.navigatorKey.currentContext!
.read<CreateSceneBloc>()
@ -395,8 +381,7 @@ class HomeCubit extends Cubit<HomeState> {
size: 28,
),
style: ButtonStyle(
foregroundColor:
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
@ -429,8 +414,7 @@ class HomeCubit extends Cubit<HomeState> {
};
static var bottomNavItems = [
defaultBottomNavBarItem(
icon: Assets.assetsIconsDashboard, label: 'Dashboard'),
defaultBottomNavBarItem(icon: Assets.assetsIconsDashboard, label: 'Dashboard'),
// defaultBottomNavBarItem(icon: Assets.assetsIconslayout, label: 'Layout'),
defaultBottomNavBarItem(icon: Assets.assetsIconsDevices, label: 'Devices'),
defaultBottomNavBarItem(icon: Assets.assetsIconsRoutines, label: 'Routine'),
@ -456,8 +440,7 @@ class HomeCubit extends Cubit<HomeState> {
void updateDevice(String deviceId) async {
try {
final response = await DevicesAPI.firmwareDevice(
deviceId: deviceId, firmwareVersion: '0');
final response = await DevicesAPI.firmwareDevice(deviceId: deviceId, firmwareVersion: '0');
if (response['success'] ?? false) {
CustomSnackBar.displaySnackBar('No updates available');
}
@ -465,8 +448,7 @@ class HomeCubit extends Cubit<HomeState> {
}
}
BottomNavigationBarItem defaultBottomNavBarItem(
{required String icon, required String label}) {
BottomNavigationBarItem defaultBottomNavBarItem({required String icon, required String label}) {
return BottomNavigationBarItem(
icon: SvgPicture.asset(icon),
activeIcon: SvgPicture.asset(

View File

@ -2,7 +2,6 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/utils/context_extension.dart';

View File

@ -1,394 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/six_scene_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
final String sixSceneId;
SixSceneBloc({
required this.sixSceneId,
}) : super(const SixSceneState()) {
on<SixSceneInitial>(_fetchDeviceStatus);
on<ChangeSwitchStatusEvent>(changeSwitchStatus);
on<LoadScenes>(_onLoadScenes);
on<SearchScenesEvent>(searchScene);
on<SaveSelectionEvent>(_onSaveSelection);
on<SelectOptionEvent>(_onOptionSelected);
on<SexSceneSwitchInitial>(_fetchFourSceneSwitches);
on<AssignDeviceScene>(assignScene);
on<GetSceneBySwitchName>(getSceneByName);
on<SelectSceneEvent>(_selectScene);
on<SixSceneInitialInfo>(fetchDeviceInfo);
on<AssignRoomEvent>(_assignDevice);
on<FetchRoomsEvent>(_fetchRoomsAndDevices);
on<DeleteDeviceEvent>(deleteDevice);
on<ToggleEnableAlarmEvent>(_toggleLowBattery);
on<UnAssignSceneEvent>(_unAssignScene);
}
final TextEditingController nameController =
TextEditingController(text: deviceName);
bool isSaving = false;
bool editName = false;
final FocusNode focusNode = FocusNode();
bool closingReminder = false;
bool waterAlarm = false;
static String deviceName = '';
SixSceneModel deviceStatus = SixSceneModel(
scene_1: '',
scene_2: '',
scene_3: '',
scene_4: '',
scene_5: '',
scene_6: '',
scene_id_group_id: '',
switch_backlight: false);
DeviceInfoModel deviceInfo = DeviceInfoModel(
activeTime: 0,
category: "",
categoryName: "",
createTime: 0,
gatewayId: "",
icon: "",
ip: "",
lat: "",
localKey: "",
lon: "",
model: "",
name: "",
nodeId: "",
online: false,
ownerId: "",
productName: "",
sub: false,
timeZone: "",
updateTime: 0,
uuid: "",
productUuid: "",
productType: "",
permissionType: "",
macAddress: "",
subspace: Subspace(
uuid: "",
createdAt: "",
updatedAt: "",
subspaceName: "",
),
);
bool enableAlarm = false;
void _toggleLowBattery(
ToggleEnableAlarmEvent event, Emitter<SixSceneState> emit) async {
emit(LoadingNewSate(device: deviceStatus));
try {
enableAlarm = event.isLowBatteryEnabled;
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
}
}
List<SubSpaceModel> roomsList = [];
void _fetchRoomsAndDevices(
FetchRoomsEvent event, Emitter<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
return;
}
}
void _assignDevice(AssignRoomEvent event, Emitter<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
if (_hasSelectionChanged) {
await HomeManagementAPI.assignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, sixSceneId);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
List<String> allDevicesIds = [];
allDevices.forEach((element) {
allDevicesIds.add(element.uuid!);
});
await HomeCubit.getInstance().fetchUnitsByUserId();
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveSelectionSuccessState());
}
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
return;
}
}
void _unAssignScene(
UnAssignSceneEvent event, Emitter<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
if (_hasSelectionChanged) {
var response = await DevicesAPI.unAssignScenesDevice(
deviceUuid: event.switchSceneUuid);
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveSelectionSuccessState());
}
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
return;
}
}
deleteDevice(DeleteDeviceEvent event, Emitter<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
var response = await DevicesAPI.resetDevise(devicesUuid: sixSceneId);
add(const SixSceneInitialInfo());
CustomSnackBar.displaySnackBar('Reset Successfully');
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
}
}
//============================ fitch devise info and status =======================
/////////////////////////////////////////////////////////////////////////////////////
Future fetchDeviceInfo(
SixSceneInitialInfo event, Emitter<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
var response = await DevicesAPI.getDeviceInfo(sixSceneId);
deviceInfo = DeviceInfoModel.fromJson(response);
deviceName = deviceInfo.name;
emit(LoadingDeviceInfo(deviceInfo: deviceInfo));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
}
}
void _fetchDeviceStatus(
SixSceneInitial event, Emitter<SixSceneState> emit) async {
emit(SixSceneLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(sixSceneId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = SixSceneModel.fromJson(
statusModelList,
);
add(const SexSceneSwitchInitial());
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
return;
}
}
//============================ assign Scene =======================
/////////////////////////////////////////////////////////////////////////////////////
String selectedFormApiSceneId = '';
void getSceneByName(
GetSceneBySwitchName event, Emitter<SixSceneState> emit) async {
try {
// emit(SixSceneLoadingState());
final response = await DevicesAPI.getSceneBySwitchName(
deviceId: sixSceneId, switchName: event.switchName);
selectedFormApiSceneId = response['scene']['uuid'];
emit(SuccessState());
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
}
}
String selectedSceneId = '';
_selectScene(SelectSceneEvent event, Emitter<SixSceneState> emit) {
emit(SixSceneLoadingState());
if (event.isSelected == false) {
selectedSceneId = '';
selectedFormApiSceneId = '';
emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
} else {
selectedSceneId = event.selectedSceneId;
}
emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
}
List<SixSceneModel> fourScene = [];
void _fetchFourSceneSwitches(
SexSceneSwitchInitial event, Emitter<SixSceneState> emit) async {
emit(SixSceneLoadingState());
try {
var response = await DevicesAPI.getDeviceSceneInfo(sixSceneId);
Map<String, String> sceneTitles = {
"scene_1": '',
"scene_2": '',
"scene_3": '',
"scene_4": '',
"scene_5": '',
"scene_6": '',
};
for (var item in response) {
if (item["switchName"] != null) {
sceneTitles[item["switchName"]] = item["scene"]["name"] ?? '';
}
}
SixSceneModel deviceStatus = SixSceneModel(
scene_1: sceneTitles["scene_1"] ?? '',
scene_2: sceneTitles["scene_2"] ?? '',
scene_3: sceneTitles["scene_3"] ?? '',
scene_4: sceneTitles["scene_4"] ?? '',
scene_5: sceneTitles["scene_5"] ?? '',
scene_6: sceneTitles["scene_6"] ?? '',
scene_id_group_id: '',
switch_backlight: '',
);
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
return;
}
}
void assignScene(AssignDeviceScene event, Emitter<SixSceneState> emit) async {
emit(SixSceneLoadingState());
try {
if (event.sceneUuid == '') {
final response = await DevicesAPI.unAssignScenesDevice(
deviceUuid: sixSceneId, switchName: event.switchName);
} else {
final response = await DevicesAPI.postDeviceSceneInfo(
deviceId: sixSceneId,
sceneUuid: event.sceneUuid,
spaceUuid: event.unit!.id,
switchName: event.switchName);
}
emit(SaveSelectionSuccessState());
CustomSnackBar.displaySnackBar('Save Successfully');
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
}
}
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
List<DeviceModel> allDevices = [];
bool switchStatus = true;
Future<void> changeSwitchStatus(
ChangeSwitchStatusEvent event, Emitter<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
switchStatus = deviceStatus.switch_backlight;
switchStatus = !switchStatus;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: sixSceneId,
code: 'switch_backlight',
value: switchStatus),
sixSceneId);
deviceStatus.switch_backlight = switchStatus;
Future.delayed(const Duration(milliseconds: 250), () {
add(const SexSceneSwitchInitial());
});
Future.delayed(const Duration(milliseconds: 250), () {
emit(ChangeSwitchState(isEnable: switchStatus));
emit(UpdateState(device: deviceStatus));
});
} catch (_) {
emit(const SixSceneFailedState(errorMessage: 'Something went wrong'));
}
}
Future<void> _onLoadScenes(
LoadScenes event, Emitter<SixSceneState> emit) async {
emit(SixSceneLoadingState());
try {
allScenes = await SceneApi.getScenesByUnitId(
event.unitId, event.unit.community.uuid,
showInDevice: event.showInDevice);
filteredScenes = allScenes;
emit(SceneLoaded(allScenes));
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(const SixSceneFailedState(errorMessage: 'Something went wrong'));
}
emit(SuccessState());
}
bool selecedScene = false;
List<ScenesModel> allScenes = [];
List<ScenesModel> filteredScenes = [];
void searchScene(SearchScenesEvent event, Emitter<SixSceneState> emit) {
emit(SixSceneLoadingState());
filteredScenes = event.query.isEmpty
? allScenes
: allScenes.where((scene) {
final sceneName = scene.name.toLowerCase();
return sceneName.contains(event.query.toLowerCase());
}).toList();
emit(SearchResultsState());
}
String _selectedOption = '';
bool _hasSelectionChanged = false;
void _onOptionSelected(SelectOptionEvent event, Emitter<SixSceneState> emit) {
emit(SixSceneLoadingState());
_selectedOption = event.selectedOption;
_hasSelectionChanged = true;
emit(OptionSelectedState(
selectedOption: _selectedOption,
hasSelectionChanged: _hasSelectionChanged));
}
void _onSaveSelection(SaveSelectionEvent event, Emitter<SixSceneState> emit) {
if (_hasSelectionChanged) {
print('Save button clicked with selected option: $_selectedOption');
_hasSelectionChanged = false;
emit(SaveSelectionSuccessState());
}
}
}

View File

@ -1,177 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/model/group_devices_model.dart';
abstract class SixSceneEvent extends Equatable {
const SixSceneEvent();
@override
List<Object> get props => [];
}
class GetSceneBySwitchName extends SixSceneEvent {
final String? switchName;
const GetSceneBySwitchName({this.switchName});
}
class SixSceneInitial extends SixSceneEvent {
const SixSceneInitial();
}
class SaveNameEvent extends SixSceneEvent {
const SaveNameEvent();
}
class UnAssignSceneEvent extends SixSceneEvent {
final String switchSceneUuid;
const UnAssignSceneEvent({required this.switchSceneUuid});
}
class SixSceneInitialInfo extends SixSceneEvent {
const SixSceneInitialInfo();
}
class SexSceneSwitchInitial extends SixSceneEvent {
const SexSceneSwitchInitial();
}
class ToggleEnableAlarmEvent extends SixSceneEvent {
final bool isLowBatteryEnabled;
const ToggleEnableAlarmEvent(this.isLowBatteryEnabled);
@override
List<Object> get props => [isLowBatteryEnabled];
}
class ToggleNotificationEvent extends SixSceneEvent {
final bool isClosingEnabled;
const ToggleNotificationEvent(this.isClosingEnabled);
@override
List<Object> get props => [isClosingEnabled];
}
class DeleteDeviceEvent extends SixSceneEvent {}
class ChangeNameEvent extends SixSceneEvent {
final bool? value;
const ChangeNameEvent({this.value});
}
class SearchFaqEvent extends SixSceneEvent {
final String query;
const SearchFaqEvent(this.query);
}
class SixSceneInitialQuestion extends SixSceneEvent {
const SixSceneInitialQuestion();
}
class ChangeSwitchStatusEvent extends SixSceneEvent {}
class FetchRoomsEvent extends SixSceneEvent {
final SpaceModel unit;
const FetchRoomsEvent({required this.unit});
@override
List<Object> get props => [unit];
}
class LoadScenes extends SixSceneEvent {
final String unitId;
final bool showInDevice;
final SpaceModel unit;
const LoadScenes(
{required this.unitId, required this.unit, this.showInDevice = false});
@override
List<Object> get props => [unitId, showInDevice];
}
class SelectSceneEvent extends SixSceneEvent {
final String selectedSceneId;
final bool isSelected;
// final String unitId;
const SelectSceneEvent({
// required this.unitId,
required this.selectedSceneId,
required this.isSelected,
});
}
class SearchScenesEvent extends SixSceneEvent {
final String query;
const SearchScenesEvent({
required this.query,
});
}
class SaveSelectionEvent extends SixSceneEvent {}
class SelectOptionEvent extends SixSceneEvent {
dynamic selectedOption;
SelectOptionEvent({
this.selectedOption,
});
}
class AddDeviceToGroup extends SixSceneEvent {
final GroupDevicesModel device;
final String icon;
const AddDeviceToGroup(this.device, this.icon);
}
class RemoveDeviceFromGroup extends SixSceneEvent {
final GroupDevicesModel device;
final String icon;
const RemoveDeviceFromGroup(this.device, this.icon);
}
class AssignDeviceScene extends SixSceneEvent {
final String? sceneUuid;
final String? switchName;
final SpaceModel? unit;
const AssignDeviceScene({
this.sceneUuid,
this.unit,
this.switchName,
});
}
class AssignRoomEvent extends SixSceneEvent {
final String roomId;
final SpaceModel unit;
final BuildContext context;
const AssignRoomEvent({
required this.roomId,
required this.unit,
required this.context,
});
@override
List<Object> get props => [
roomId,
unit,
context,
];
}
class ToggleUpdateEvent extends SixSceneEvent {
final bool? isUpdateEnabled;
const ToggleUpdateEvent({this.isUpdateEnabled});
}
class ToggleHelpfulEvent extends SixSceneEvent {
final bool? isHelpful;
const ToggleHelpfulEvent({this.isHelpful});
}

View File

@ -1,125 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/group_devices_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart';
import 'package:syncrow_app/features/devices/model/six_scene_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
class SixSceneState extends Equatable {
const SixSceneState();
@override
List<Object> get props => [];
}
class SixSceneLoadingState extends SixSceneState {}
class SaveState extends SixSceneState {}
class UpdateStateList extends SixSceneState {
final List<GroupDevicesModel> groupDevices;
final List<GroupDevicesModel> devices;
const UpdateStateList({required this.groupDevices, required this.devices});
}
class SixSceneFailedState extends SixSceneState {
final String errorMessage;
const SixSceneFailedState({required this.errorMessage});
@override
List<Object> get props => [errorMessage];
}
class UpdateState extends SixSceneState {
final SixSceneModel device;
const UpdateState({required this.device});
@override
List<Object> get props => [device];
}
class LoadingNewSate extends SixSceneState {
final SixSceneModel device;
const LoadingNewSate({required this.device});
@override
List<Object> get props => [device];
}
class NameEditingState extends SixSceneState {
final bool editName;
const NameEditingState({required this.editName});
}
class FaqLoadedState extends SixSceneState {
final List<SixSceneQuestionModel> filteredFaqQuestions;
const FaqLoadedState({this.filteredFaqQuestions = const []});
}
class FaqSearchState extends SixSceneState {
final List<SixSceneQuestionModel> filteredFaqQuestions;
const FaqSearchState({this.filteredFaqQuestions = const []});
}
class FetchRoomsState extends SixSceneState {
final List<SubSpaceModel> roomsList;
final List<DeviceModel> devicesList;
const FetchRoomsState({required this.devicesList, required this.roomsList});
@override
List<Object> get props => [devicesList];
}
class ChangeSwitchState extends SixSceneState {
final bool isEnable;
const ChangeSwitchState({required this.isEnable});
}
class SceneLoaded extends SixSceneState {
final List<ScenesModel> scenes;
final String? loadingSceneId;
final Map<String, bool> loadingStates;
const SceneLoaded(this.scenes,
{this.loadingSceneId, this.loadingStates = const {}});
}
class SearchResultsState extends SixSceneState {}
class SuccessState extends SixSceneState {}
class SaveSelectionSuccessState extends SixSceneState {}
class OptionSelectedState extends SixSceneState {
final String selectedOption;
final bool hasSelectionChanged;
const OptionSelectedState({
required this.selectedOption,
required this.hasSelectionChanged,
});
@override
List<Object> get props => [selectedOption, hasSelectionChanged];
}
class SceneSelectionUpdatedState extends SixSceneState {
final String selectedSceneId;
const SceneSelectionUpdatedState({required this.selectedSceneId});
}
class LoadingDeviceInfo extends SixSceneState {
final DeviceInfoModel deviceInfo;
const LoadingDeviceInfo({required this.deviceInfo});
@override
List<Object> get props => [deviceInfo];
}

View File

@ -1,483 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_switch_model.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/model/group_devices_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
final String deviceId;
DeviceSettingBloc({
required this.deviceId,
}) : super(const DeviceSettingState()) {
on<DeviceSettingInitial>(_fetchDeviceStatus);
on<DeviceSettingInitialInfo>(fetchDeviceInfo);
on<SaveNameEvent>(saveName);
on<ToggleNotificationEvent>(_toggleNotification);
on<ChangeNameEvent>(_changeName);
on<SearchFaqEvent>(_onSearchFaq);
on<FetchRoomsEvent>(_fetchRoomsAndDevices);
on<LoadSettings>(_onLoadSettings);
on<SearchSettingsEvent>(searchSetting);
on<AssignRoomEvent>(_assignDevice);
on<AddDeviceToGroup>(_addDeviceToGroup);
on<RemoveDeviceFromGroup>(_removeDeviceFromGroup);
on<DeviceSettingInitialQuestion>(_onDeviceSettingInitial);
on<FetchDeviceSetting>(_fetchDeviceSetting);
on<GetSettingBySwitchName>(getSettingByName);
on<SelectSettingEvent>(_selectSetting);
on<DeleteDeviceEvent>(deleteDevice);
on<ToggleEnableAlarmEvent>(_toggleLowBattery);
on<ToggleUpdateEvent>(_toggleUpdate);
on<ToggleHelpfulEvent>(_toggleHelpful);
on<SelectOptionEvent>(_onOptionSelected);
}
final TextEditingController nameController =
TextEditingController(text: deviceName);
bool isSaving = false;
bool editName = false;
final FocusNode focusNode = FocusNode();
bool closingReminder = false;
bool waterAlarm = false;
static String deviceName = '';
static String selectedRoomId = '';
bool selecedSetting = false;
bool enableAlarm = false;
List<FourSceneSwitchModel> fourSetting = [];
String _selectedOption = '';
bool _hasSelectionChanged = false;
FourSceneModelState deviceStatus = FourSceneModelState(
scene_1: '',
scene_2: '',
scene_3: '',
scene_4: '',
scene_id_group_id: '',
switch_backlight: false);
DeviceInfoModel deviceInfo = DeviceInfoModel(
activeTime: 0,
category: "",
categoryName: "",
createTime: 0,
gatewayId: "",
icon: "",
ip: "",
lat: "",
localKey: "",
lon: "",
model: "",
name: "",
nodeId: "",
online: false,
ownerId: "",
productName: "",
sub: false,
timeZone: "",
updateTime: 0,
uuid: "",
productUuid: "",
productType: "",
permissionType: "",
macAddress: "",
subspace: Subspace(
uuid: "",
createdAt: "",
updatedAt: "",
subspaceName: "",
),
);
//============================ get Setting and assign scene =======================
String selectedFormApiSettingId = '';
String selectedSettingId = '';
_selectSetting(SelectSettingEvent event, Emitter<DeviceSettingState> emit) {
emit(DeviceSettingLoadingState());
selectedSettingId = event.selectedSettingId;
emit(SettingSelectionUpdatedState(selectedSettingId: selectedSettingId));
}
void getSettingByName(
GetSettingBySwitchName event, Emitter<DeviceSettingState> emit) async {
// emit(DeviceSettingLoadingState());
try {
final response = await DevicesAPI.getSceneBySwitchName(
deviceId: deviceId, switchName: event.switchName);
selectedFormApiSettingId = response['scene']['uuid'];
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
}
}
void _fetchDeviceSetting(
FetchDeviceSetting event, Emitter<DeviceSettingState> emit) async {
emit(DeviceSettingLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(deviceId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = FourSceneModelState.fromJson(
statusModelList,
);
emit(UpdateState(device: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
return;
}
}
//===================== fetch Device Status and info =======================
void _toggleLowBattery(
ToggleEnableAlarmEvent event, Emitter<DeviceSettingState> emit) async {
emit(LoadingNewSate(device: deviceStatus));
try {
enableAlarm = event.isLowBatteryEnabled;
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
}
}
void _fetchDeviceStatus(
DeviceSettingInitial event, Emitter<DeviceSettingState> emit) async {
emit(DeviceSettingLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(deviceId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = FourSceneModelState.fromJson(
statusModelList,
);
emit(SuccessState());
// add(const DeviceSettingSwitchInitial());
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
return;
}
}
Future fetchDeviceInfo(
DeviceSettingInitialInfo event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
var response = await DevicesAPI.getDeviceInfo(deviceId);
deviceInfo = DeviceInfoModel.fromJson(response);
deviceName = deviceInfo.name;
emit(LoadingDeviceInfo(deviceInfo: deviceInfo));
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
}
}
void _onSearchFaq(SearchFaqEvent event, Emitter<DeviceSettingState> emit) {
emit(DeviceSettingLoadingState());
List<QuestionModel> _faqQuestions = faqQuestions.where((question) {
return question.question
.toLowerCase()
.contains(event.query.toLowerCase());
}).toList();
emit(FaqSearchState(filteredFaqQuestions: _faqQuestions));
}
//============================ assign Device ==================================
//////////////////////////////////////////////////////////////////////////////
void _toggleNotification(
ToggleNotificationEvent event, Emitter<DeviceSettingState> emit) async {
emit(LoadingNewSate(device: deviceStatus));
try {
enableAlarm = event.isClosingEnabled;
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
}
}
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
//========================= Question and faq ================================
final List<QuestionModel> faqQuestions = [
QuestionModel(
id: 1,
question:
'How does an 4 Setting Switch work? How long will an 4 Setting Switch persist?',
answer:
'Yes. In scenes with high detection requirements, we recommend that you choose phone or message notification in Automation.',
),
QuestionModel(
id: 2,
question: 'Does the 4 Setting Switch support sending notifications?',
answer:
'The SOS alarm will persist until it is manually turned off or after a set time.',
),
QuestionModel(
id: 3,
question:
'Why does the data statistics in the device panel not show the correct data?',
answer: 'Try restarting the device. If it persists, contact support.',
),
QuestionModel(
id: 4,
question:
'How long will the App show offline after a device (low-power devices and normal devices) is powered...',
answer:
'No, a network connection is required to send the alert to your contacts.',
),
];
bool? isHelpful;
void _toggleHelpful(
ToggleHelpfulEvent event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
isHelpful = event.isHelpful!;
emit(SaveState());
} catch (e) {
emit(
const DeviceSettingFailedState(errorMessage: 'Something went wrong'));
}
}
Future<void> _onDeviceSettingInitial(DeviceSettingInitialQuestion event,
Emitter<DeviceSettingState> emit) async {
emit(DeviceSettingLoadingState());
emit(FaqLoadedState(filteredFaqQuestions: faqQuestions));
}
List<DeviceModel> allDevices = [];
List<SubSpaceModel> roomsList = [];
bool switchStatus = true;
Future<void> _onLoadSettings(
LoadSettings event, Emitter<DeviceSettingState> emit) async {
emit(DeviceSettingLoadingState());
try {
if (event.unitId.isNotEmpty) {
// allSettings = await DevicesAPI.getDveByUnitId(
// event.unitId, event.unit.community.uuid,
// showInDevice: event.showInDevice);
filteredSettings = allSettings;
emit(SettingLoaded(allSettings));
} else {
emit(const DeviceSettingFailedState(errorMessage: 'Unit ID is empty'));
}
} catch (e) {
emit(
const DeviceSettingFailedState(errorMessage: 'Something went wrong'));
}
}
List<ScenesModel> allSettings = [];
List<ScenesModel> filteredSettings = [];
void searchSetting(
SearchSettingsEvent event, Emitter<DeviceSettingState> emit) {
emit(DeviceSettingLoadingState());
filteredSettings = event.query.isEmpty
? allSettings
: allSettings.where((scene) {
final sceneName = scene.name?.toLowerCase() ?? '';
return sceneName.contains(event.query.toLowerCase());
}).toList();
emit(SearchResultsState());
}
List<GroupDevicesModel> groupDevices = [
GroupDevicesModel(
dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Setting Switch')
];
List<GroupDevicesModel> devices = [
GroupDevicesModel(
dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Setting Switch')
];
// Handler for AddDeviceToGroup
void _addDeviceToGroup(
AddDeviceToGroup event, Emitter<DeviceSettingState> emit) {
devices.remove(event.device);
groupDevices.add(event.device);
for (var device in groupDevices) {
device.icon = event.icon;
}
emit(UpdateStateList(groupDevices: groupDevices, devices: devices));
}
// Handler for RemoveDeviceFromGroup
void _removeDeviceFromGroup(
RemoveDeviceFromGroup event, Emitter<DeviceSettingState> emit) {
groupDevices.remove(event.device);
devices.add(event.device);
for (var device in groupDevices) {
device.icon = event.icon;
}
emit(UpdateStateList(groupDevices: groupDevices, devices: devices));
}
//=========================== assign device to room ==========================
void _assignDevice(
AssignRoomEvent event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
if (_hasSelectionChanged) {
await HomeManagementAPI.assignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, deviceId);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
List<String> allDevicesIds = [];
allDevices.forEach((element) {
allDevicesIds.add(element.uuid!);
});
await HomeCubit.getInstance().fetchUnitsByUserId();
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveSelectionSuccessState());
}
} catch (e) {
emit(
const DeviceSettingFailedState(errorMessage: 'Something went wrong'));
return;
}
}
void _fetchRoomsAndDevices(
FetchRoomsEvent event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(
const DeviceSettingFailedState(errorMessage: 'Something went wrong'));
return;
}
}
//============================ setting name ==================================
//////////////////////////////////////////////////////////////////////////////
void _changeName(ChangeNameEvent event, Emitter<DeviceSettingState> emit) {
emit(DeviceSettingLoadingState());
editName = event.value!;
if (editName) {
Future.delayed(const Duration(milliseconds: 500), () {
focusNode.requestFocus();
});
} else {
focusNode.unfocus();
}
emit(NameEditingState(editName: editName));
}
bool _validateInputs() {
final nameError = fullNameValidator(nameController.text);
if (nameError != null) {
CustomSnackBar.displaySnackBar(nameError);
return true;
}
return false;
}
String? fullNameValidator(String? value) {
if (value == null) return 'name is required';
final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim();
if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) {
return 'name must be between 2 and 30 characters long';
}
if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) {
return 'Only alphanumeric characters, space, dash and single quote are allowed';
}
return null;
}
Future<void> saveName(
SaveNameEvent event, Emitter<DeviceSettingState> emit) async {
if (_validateInputs()) return;
try {
add(const ChangeNameEvent(value: false));
isSaving = true;
emit(DeviceSettingLoadingState());
var response = await DevicesAPI.putDeviceName(
deviceId: deviceId, deviceName: nameController.text);
add(const DeviceSettingInitialInfo());
await HomeCubit.getInstance().fetchUnitsByUserId();
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState());
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
} finally {
isSaving = false;
}
}
//====================== update device ==============================
bool enableUpdate = false;
void _toggleUpdate(
ToggleUpdateEvent event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
enableUpdate = event.isUpdateEnabled!;
emit(SaveState());
} catch (e) {
emit(
const DeviceSettingFailedState(errorMessage: 'Something went wrong'));
}
}
deleteDevice(
DeleteDeviceEvent event, Emitter<DeviceSettingState> emit) async {
try {
emit(DeviceSettingLoadingState());
var response = await DevicesAPI.resetDevise(devicesUuid: deviceId);
CustomSnackBar.displaySnackBar('Reset Successfully');
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(DeviceSettingFailedState(errorMessage: e.toString()));
return;
}
}
void _onOptionSelected(
SelectOptionEvent event, Emitter<DeviceSettingState> emit) {
emit(DeviceSettingLoadingState());
_selectedOption = event.selectedOption;
_hasSelectionChanged = true;
emit(OptionSelectedState(
selectedOption: _selectedOption,
hasSelectionChanged: _hasSelectionChanged));
}
}

View File

@ -1,171 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/model/group_devices_model.dart';
abstract class DeviceSettingEvent extends Equatable {
const DeviceSettingEvent();
@override
List<Object> get props => [];
}
class DeviceSettingInitialInfo extends DeviceSettingEvent {
const DeviceSettingInitialInfo();
}
class DeviceSettingInitial extends DeviceSettingEvent {
const DeviceSettingInitial();
}
class SaveNameEvent extends DeviceSettingEvent {
final String? deviceName;
const SaveNameEvent({this.deviceName});
}
class ToggleEnableAlarmEvent extends DeviceSettingEvent {
final bool isLowBatteryEnabled;
const ToggleEnableAlarmEvent(this.isLowBatteryEnabled);
@override
List<Object> get props => [isLowBatteryEnabled];
}
class ToggleNotificationEvent extends DeviceSettingEvent {
final bool isClosingEnabled;
const ToggleNotificationEvent(this.isClosingEnabled);
@override
List<Object> get props => [isClosingEnabled];
}
class DeleteDeviceEvent extends DeviceSettingEvent {}
class ChangeNameEvent extends DeviceSettingEvent {
final bool? value;
const ChangeNameEvent({this.value});
}
class SearchFaqEvent extends DeviceSettingEvent {
final String query;
const SearchFaqEvent(this.query);
}
class DeviceSettingInitialQuestion extends DeviceSettingEvent {
const DeviceSettingInitialQuestion();
}
// class ChangeSwitchStatusEvent extends DeviceSettingEvent {}
class FetchRoomsEvent extends DeviceSettingEvent {
final SpaceModel unit;
const FetchRoomsEvent({required this.unit});
@override
List<Object> get props => [unit];
}
class LoadSettings extends DeviceSettingEvent {
final String unitId;
final bool showInDevice;
final SpaceModel unit;
const LoadSettings(
{required this.unitId, required this.unit, this.showInDevice = false});
@override
List<Object> get props => [unitId, showInDevice];
}
class SelectSettingEvent extends DeviceSettingEvent {
final String selectedSettingId;
// final String unitId;
const SelectSettingEvent({
// required this.unitId,
required this.selectedSettingId,
});
}
class SearchSettingsEvent extends DeviceSettingEvent {
final String query;
const SearchSettingsEvent({
required this.query,
});
}
class SelectOptionEvent extends DeviceSettingEvent {
final dynamic selectedOption;
const SelectOptionEvent({
this.selectedOption,
});
}
class AddDeviceToGroup extends DeviceSettingEvent {
final GroupDevicesModel device;
final String icon;
const AddDeviceToGroup(this.device, this.icon);
}
class RemoveDeviceFromGroup extends DeviceSettingEvent {
final GroupDevicesModel device;
final String icon;
const RemoveDeviceFromGroup(this.device, this.icon);
}
class AssignRoomEvent extends DeviceSettingEvent {
final String roomId;
final SpaceModel unit;
final BuildContext context;
const AssignRoomEvent({
required this.roomId,
required this.unit,
required this.context,
});
@override
List<Object> get props => [
roomId,
unit,
context,
];
}
class FetchDeviceSetting extends DeviceSettingEvent {}
// class DeviceSettingSwitchInitial extends DeviceSettingEvent {
// const DeviceSettingSwitchInitial();
// }
class AssignDeviceSetting extends DeviceSettingEvent {
final String? sceneUuid;
final String? switchName;
final SpaceModel? unit;
const AssignDeviceSetting({
this.sceneUuid,
this.unit,
this.switchName,
});
}
class GetSettingBySwitchName extends DeviceSettingEvent {
final String? switchName;
const GetSettingBySwitchName({this.switchName});
}
class ToggleUpdateEvent extends DeviceSettingEvent {
final bool? isUpdateEnabled;
const ToggleUpdateEvent({this.isUpdateEnabled});
}
class ToggleHelpfulEvent extends DeviceSettingEvent {
final bool? isHelpful;
const ToggleHelpfulEvent({this.isHelpful});
}

View File

@ -1,125 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_model.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/model/group_devices_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
class DeviceSettingState extends Equatable {
const DeviceSettingState();
@override
List<Object> get props => [];
}
class DeviceSettingLoadingState extends DeviceSettingState {}
class UpdateStateList extends DeviceSettingState {
final List<GroupDevicesModel> groupDevices;
final List<GroupDevicesModel> devices;
const UpdateStateList({required this.groupDevices, required this.devices});
}
class DeviceSettingFailedState extends DeviceSettingState {
final String errorMessage;
const DeviceSettingFailedState({required this.errorMessage});
@override
List<Object> get props => [errorMessage];
}
class UpdateState extends DeviceSettingState {
final FourSceneModelState device;
const UpdateState({required this.device});
@override
List<Object> get props => [device];
}
class LoadingNewSate extends DeviceSettingState {
final FourSceneModelState device;
const LoadingNewSate({required this.device});
@override
List<Object> get props => [device];
}
class NameEditingState extends DeviceSettingState {
final bool editName;
const NameEditingState({required this.editName});
}
class FaqLoadedState extends DeviceSettingState {
final List<QuestionModel> filteredFaqQuestions;
const FaqLoadedState({this.filteredFaqQuestions = const []});
}
class FaqSearchState extends DeviceSettingState {
final List<QuestionModel> filteredFaqQuestions;
const FaqSearchState({this.filteredFaqQuestions = const []});
}
class FetchRoomsState extends DeviceSettingState {
final List<SubSpaceModel> roomsList;
final List<DeviceModel> devicesList;
const FetchRoomsState({required this.devicesList, required this.roomsList});
@override
List<Object> get props => [devicesList];
}
class ChangeSwitchState extends DeviceSettingState {
final bool isEnable;
const ChangeSwitchState({required this.isEnable});
}
class SettingLoaded extends DeviceSettingState {
final List<ScenesModel> scenes;
final String? loadingSettingId;
final Map<String, bool> loadingStates;
const SettingLoaded(this.scenes,
{this.loadingSettingId, this.loadingStates = const {}});
}
class SearchResultsState extends DeviceSettingState {}
class SaveState extends DeviceSettingState {}
class SuccessState extends DeviceSettingState {}
class SaveSelectionSuccessState extends DeviceSettingState {}
class OptionSelectedState extends DeviceSettingState {
final String selectedOption;
final bool hasSelectionChanged;
const OptionSelectedState({
required this.selectedOption,
required this.hasSelectionChanged,
});
@override
List<Object> get props => [selectedOption, hasSelectionChanged];
}
class LoadingDeviceInfo extends DeviceSettingState {
final DeviceInfoModel deviceInfo;
const LoadingDeviceInfo({required this.deviceInfo});
@override
List<Object> get props => [deviceInfo];
}
class SettingSelectionUpdatedState extends DeviceSettingState {
final String selectedSettingId;
const SettingSelectionUpdatedState({required this.selectedSettingId});
}

View File

@ -1,330 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_switch_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
final String fourSceneId;
FourSceneBloc({
required this.fourSceneId,
}) : super(const FourSceneState()) {
on<FourSceneInitial>(_fetchDeviceStatus);
on<FourSceneInitialInfo>(fetchDeviceInfo);
on<ToggleNotificationEvent>(_toggleNotification);
on<ChangeSwitchStatusEvent>(changeSwitchStatus);
on<LoadScenes>(_onLoadScenes);
on<SearchScenesEvent>(searchScene);
on<SelectOptionEvent>(_onOptionSelected);
on<FetchDeviceScene>(_fetchDeviceScene);
on<FourSceneSwitchInitial>(_fetchFourSceneSwitches);
on<AssignDeviceScene>(assignScene);
on<GetSceneBySwitchName>(getSceneByName);
on<SelectSceneEvent>(_selectScene);
on<ToggleEnableAlarmEvent>(_toggleLowBattery);
}
final TextEditingController nameController =
TextEditingController(text: deviceName);
bool isSaving = false;
bool editName = false;
final FocusNode focusNode = FocusNode();
bool closingReminder = false;
bool waterAlarm = false;
static String deviceName = '';
static String selectedRoomId = '';
bool selecedScene = false;
bool enableAlarm = false;
List<FourSceneSwitchModel> fourScene = [];
String _selectedOption = '';
bool _hasSelectionChanged = false;
FourSceneModelState deviceStatus = FourSceneModelState(
scene_1: '',
scene_2: '',
scene_3: '',
scene_4: '',
scene_id_group_id: '',
switch_backlight: false);
DeviceInfoModel deviceInfo = DeviceInfoModel(
activeTime: 0,
category: "",
categoryName: "",
createTime: 0,
gatewayId: "",
icon: "",
ip: "",
lat: "",
localKey: "",
lon: "",
model: "",
name: "",
nodeId: "",
online: false,
ownerId: "",
productName: "",
sub: false,
timeZone: "",
updateTime: 0,
uuid: "",
productUuid: "",
productType: "",
permissionType: "",
macAddress: "",
subspace: Subspace(
uuid: "",
createdAt: "",
updatedAt: "",
subspaceName: "",
),
);
//============================ get Scene and assign scene =======================
String selectedFormApiSceneId = '';
String selectedSceneId = '';
_selectScene(SelectSceneEvent event, Emitter<FourSceneState> emit) {
emit(FourSceneLoadingState());
if (event.isSelected == false) {
selectedSceneId = '';
selectedFormApiSceneId = '';
emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
} else {
selectedSceneId = event.selectedSceneId;
}
emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
}
void getSceneByName(
GetSceneBySwitchName event, Emitter<FourSceneState> emit) async {
// emit(FourSceneLoadingState());
try {
final response = await DevicesAPI.getSceneBySwitchName(
deviceId: fourSceneId, switchName: event.switchName);
selectedFormApiSceneId = response['scene']['uuid'];
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
}
}
void _onOptionSelected(
SelectOptionEvent event, Emitter<FourSceneState> emit) {
emit(FourSceneLoadingState());
_selectedOption = event.selectedOption;
_hasSelectionChanged = true;
emit(OptionSelectedState(
selectedOption: _selectedOption,
hasSelectionChanged: _hasSelectionChanged));
}
void _fetchFourSceneSwitches(
FourSceneSwitchInitial event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState());
try {
var response = await DevicesAPI.getDeviceSceneInfo(fourSceneId);
Map<String, String> sceneTitles = {
"scene_1": '',
"scene_2": '',
"scene_3": '',
"scene_4": '',
};
for (var item in response) {
if (item["switchName"] != null) {
sceneTitles[item["switchName"]] = item["scene"]["name"] ?? '';
}
}
FourSceneModelState deviceStatus = FourSceneModelState(
scene_1: sceneTitles["scene_1"] ?? '',
scene_2: sceneTitles["scene_2"] ?? '',
scene_3: sceneTitles["scene_3"] ?? '',
scene_4: sceneTitles["scene_4"] ?? '',
scene_id_group_id: '',
switch_backlight: '',
);
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
return;
}
}
void assignScene(
AssignDeviceScene event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState());
try {
if (event.sceneUuid == '') {
final response = await DevicesAPI.unAssignScenesDevice(
deviceUuid: fourSceneId, switchName: event.switchName);
} else {
final response = await DevicesAPI.postDeviceSceneInfo(
deviceId: fourSceneId,
sceneUuid: event.sceneUuid,
spaceUuid: event.unit!.id,
switchName: event.switchName);
}
emit(SaveSelectionSuccessState());
CustomSnackBar.displaySnackBar('Save Successfully');
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
}
}
void _fetchDeviceScene(
FetchDeviceScene event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(fourSceneId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = FourSceneModelState.fromJson(
statusModelList,
);
emit(UpdateState(device: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
return;
}
}
//===================== fetch Device Status and info =======================
void _toggleLowBattery(
ToggleEnableAlarmEvent event, Emitter<FourSceneState> emit) async {
emit(LoadingNewSate(device: deviceStatus));
try {
enableAlarm = event.isLowBatteryEnabled;
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
}
}
void _fetchDeviceStatus(
FourSceneInitial event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(fourSceneId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = FourSceneModelState.fromJson(
statusModelList,
);
add(const FourSceneSwitchInitial());
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
return;
}
}
Future fetchDeviceInfo(
FourSceneInitialInfo event, Emitter<FourSceneState> emit) async {
try {
emit(FourSceneLoadingState());
var response = await DevicesAPI.getDeviceInfo(fourSceneId);
deviceInfo = DeviceInfoModel.fromJson(response);
deviceName = deviceInfo.name;
emit(LoadingDeviceInfo(deviceInfo: deviceInfo));
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
}
}
//============================ assign Device ==================================
//////////////////////////////////////////////////////////////////////////////
void _toggleNotification(
ToggleNotificationEvent event, Emitter<FourSceneState> emit) async {
emit(LoadingNewSate(device: deviceStatus));
try {
enableAlarm = event.isClosingEnabled;
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(FourSceneFailedState(errorMessage: e.toString()));
}
}
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
List<DeviceModel> allDevices = [];
List<SubSpaceModel> roomsList = [];
bool switchStatus = true;
Future<void> changeSwitchStatus(
ChangeSwitchStatusEvent event, Emitter<FourSceneState> emit) async {
try {
emit(FourSceneLoadingState());
switchStatus = deviceStatus.switch_backlight;
switchStatus = !switchStatus;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: fourSceneId,
code: 'switch_backlight',
value: switchStatus),
fourSceneId);
deviceStatus.switch_backlight = switchStatus;
Future.delayed(const Duration(milliseconds: 200), () {
add(const FourSceneSwitchInitial());
});
Future.delayed(const Duration(milliseconds: 200), () {
emit(ChangeSwitchState(isEnable: switchStatus));
emit(UpdateState(device: deviceStatus));
});
} catch (_) {
add(const FourSceneInitial());
}
}
Future<void> _onLoadScenes(
LoadScenes event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState());
try {
if (event.unitId.isNotEmpty) {
allScenes = await SceneApi.getScenesByUnitId(
event.unitId, event.unit.community.uuid,
showInDevice: event.showInDevice);
filteredScenes = allScenes;
emit(SceneLoaded(allScenes));
} else {
emit(const FourSceneFailedState(errorMessage: 'Unit ID is empty'));
}
} catch (e) {
emit(const FourSceneFailedState(errorMessage: 'Something went wrong'));
}
}
List<ScenesModel> allScenes = [];
List<ScenesModel> filteredScenes = [];
void searchScene(SearchScenesEvent event, Emitter<FourSceneState> emit) {
emit(FourSceneLoadingState());
filteredScenes = event.query.isEmpty
? allScenes
: allScenes.where((scene) {
final sceneName = scene.name?.toLowerCase() ?? '';
return sceneName.contains(event.query.toLowerCase());
}).toList();
emit(SearchResultsState());
}
}

View File

@ -1,180 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/model/group_devices_model.dart';
abstract class FourSceneEvent extends Equatable {
const FourSceneEvent();
@override
List<Object> get props => [];
}
class FourSceneInitialInfo extends FourSceneEvent {
const FourSceneInitialInfo();
}
class FourSceneInitial extends FourSceneEvent {
const FourSceneInitial();
}
class SaveNameEvent extends FourSceneEvent {
final String? deviceName;
const SaveNameEvent({this.deviceName});
}
class ToggleEnableAlarmEvent extends FourSceneEvent {
final bool isLowBatteryEnabled;
const ToggleEnableAlarmEvent(this.isLowBatteryEnabled);
@override
List<Object> get props => [isLowBatteryEnabled];
}
class ToggleNotificationEvent extends FourSceneEvent {
final bool isClosingEnabled;
const ToggleNotificationEvent(this.isClosingEnabled);
@override
List<Object> get props => [isClosingEnabled];
}
class DeleteDeviceEvent extends FourSceneEvent {}
class ChangeNameEvent extends FourSceneEvent {
final bool? value;
const ChangeNameEvent({this.value});
}
class SearchFaqEvent extends FourSceneEvent {
final String query;
const SearchFaqEvent(this.query);
}
class FourSceneInitialQuestion extends FourSceneEvent {
const FourSceneInitialQuestion();
}
class ChangeSwitchStatusEvent extends FourSceneEvent {}
class FetchRoomsEvent extends FourSceneEvent {
final SpaceModel unit;
const FetchRoomsEvent({required this.unit});
@override
List<Object> get props => [unit];
}
class LoadScenes extends FourSceneEvent {
final String unitId;
final bool showInDevice;
final SpaceModel unit;
const LoadScenes(
{required this.unitId, required this.unit, this.showInDevice = false});
@override
List<Object> get props => [unitId, showInDevice];
}
class SelectSceneEvent extends FourSceneEvent {
final String selectedSceneId;
final bool isSelected;
// final String unitId;
const SelectSceneEvent({
// required this.unitId,
required this.selectedSceneId,
required this.isSelected,
});
}
class SearchScenesEvent extends FourSceneEvent {
final String query;
const SearchScenesEvent({
required this.query,
});
}
class SelectOptionEvent extends FourSceneEvent {
final dynamic selectedOption;
const SelectOptionEvent({
this.selectedOption,
});
}
class AddDeviceToGroup extends FourSceneEvent {
final GroupDevicesModel device;
final String icon;
const AddDeviceToGroup(this.device, this.icon);
}
class RemoveDeviceFromGroup extends FourSceneEvent {
final GroupDevicesModel device;
final String icon;
const RemoveDeviceFromGroup(this.device, this.icon);
}
class AssignRoomEvent extends FourSceneEvent {
final String roomId;
final SpaceModel unit;
final BuildContext context;
const AssignRoomEvent({
required this.roomId,
required this.unit,
required this.context,
});
@override
List<Object> get props => [
roomId,
unit,
context,
];
}
class FetchDeviceScene extends FourSceneEvent {}
class FourSceneSwitchInitial extends FourSceneEvent {
const FourSceneSwitchInitial();
}
class UnAssignSceneEvent extends FourSceneEvent {
final String deviceUuid;
final String switchName;
const UnAssignSceneEvent(
{required this.deviceUuid, required this.switchName});
}
class AssignDeviceScene extends FourSceneEvent {
final String? sceneUuid;
final String? switchName;
final SpaceModel? unit;
const AssignDeviceScene({
this.sceneUuid,
this.unit,
this.switchName,
});
}
class GetSceneBySwitchName extends FourSceneEvent {
final String? switchName;
const GetSceneBySwitchName({this.switchName});
}
class ToggleUpdateEvent extends FourSceneEvent {
final bool? isUpdateEnabled;
const ToggleUpdateEvent({this.isUpdateEnabled});
}
class ToggleHelpfulEvent extends FourSceneEvent {
final bool? isHelpful;
const ToggleHelpfulEvent({this.isHelpful});
}

View File

@ -1,124 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_model.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/model/group_devices_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
class FourSceneState extends Equatable {
const FourSceneState();
@override
List<Object> get props => [];
}
class FourSceneLoadingState extends FourSceneState {}
class UpdateStateList extends FourSceneState {
final List<GroupDevicesModel> groupDevices;
final List<GroupDevicesModel> devices;
const UpdateStateList({required this.groupDevices, required this.devices});
}
class FourSceneFailedState extends FourSceneState {
final String errorMessage;
const FourSceneFailedState({required this.errorMessage});
@override
List<Object> get props => [errorMessage];
}
class UpdateState extends FourSceneState {
final FourSceneModelState device;
const UpdateState({required this.device});
@override
List<Object> get props => [device];
}
class LoadingNewSate extends FourSceneState {
final FourSceneModelState device;
const LoadingNewSate({required this.device});
@override
List<Object> get props => [device];
}
class NameEditingState extends FourSceneState {
final bool editName;
const NameEditingState({required this.editName});
}
class FaqLoadedState extends FourSceneState {
final List<QuestionModel> filteredFaqQuestions;
const FaqLoadedState({this.filteredFaqQuestions = const []});
}
class FaqSearchState extends FourSceneState {
final List<QuestionModel> filteredFaqQuestions;
const FaqSearchState({this.filteredFaqQuestions = const []});
}
class FetchRoomsState extends FourSceneState {
final List<SubSpaceModel> roomsList;
final List<DeviceModel> devicesList;
const FetchRoomsState({required this.devicesList, required this.roomsList});
@override
List<Object> get props => [devicesList];
}
class ChangeSwitchState extends FourSceneState {
final bool isEnable;
const ChangeSwitchState({required this.isEnable});
}
class SceneLoaded extends FourSceneState {
final List<ScenesModel> scenes;
final String? loadingSceneId;
final Map<String, bool> loadingStates;
const SceneLoaded(this.scenes,
{this.loadingSceneId, this.loadingStates = const {}});
}
class SearchResultsState extends FourSceneState {}
class SaveState extends FourSceneState {}
class SaveSelectionSuccessState extends FourSceneState {}
class OptionSelectedState extends FourSceneState {
final String selectedOption;
final bool hasSelectionChanged;
const OptionSelectedState({
required this.selectedOption,
required this.hasSelectionChanged,
});
@override
List<Object> get props => [selectedOption, hasSelectionChanged];
}
class LoadingDeviceInfo extends FourSceneState {
final DeviceInfoModel deviceInfo;
const LoadingDeviceInfo({required this.deviceInfo});
@override
List<Object> get props => [deviceInfo];
}
class SceneSelectionUpdatedState extends FourSceneState {
final String selectedSceneId;
const SceneSelectionUpdatedState({required this.selectedSceneId});
}

View File

@ -2,24 +2,17 @@ import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class SosBloc extends Bloc<SosEvent, SosState> {
final String sosId;
@ -36,55 +29,64 @@ class SosBloc extends Bloc<SosEvent, SosState> {
on<FetchRoomsEvent>(_fetchRoomsAndDevices);
on<SelectOptionEvent>(_onOptionSelected);
on<SaveSelectionEvent>(_onSaveSelection);
on<AssignRoomEvent>(_assignDevice);
on<SosInitialDeviseInfo>(fetchDeviceInfo);
on<SaveNameEvent>(saveName);
on<ToggleUpdateEvent>(_toggleUpdate);
on<ToggleHelpfulEvent>(_toggleHelpful);
// on<ToggleWaterLeakAlarmEvent>(_toggleWaterLeakAlarm);
}
final TextEditingController nameController =
TextEditingController(text: deviceName);
TextEditingController(text: '${'firstName'}');
bool isSaving = false;
bool editName = false;
final FocusNode focusNode = FocusNode();
Timer? _timer;
bool enableAlarm = false;
bool closingReminder = false;
bool waterAlarm = false;
SosModel deviceStatus =
SosModel(sosContactState: 'sos', batteryPercentage: 0);
SosModel(sosContactState: 'normal', batteryPercentage: 0);
DeviceInfoModel deviceInfo = DeviceInfoModel(
activeTime: 0,
category: "",
categoryName: "",
createTime: 0,
gatewayId: "",
icon: "",
ip: "",
lat: "",
localKey: "",
lon: "",
model: "",
name: "",
nodeId: "",
online: false,
ownerId: "",
productName: "",
sub: false,
timeZone: "",
updateTime: 0,
uuid: "",
productUuid: "",
productType: "",
permissionType: "",
macAddress: "",
subspace: Subspace(
uuid: "",
createdAt: "",
updatedAt: "",
subspaceName: "",
),
);
void _fetchStatus(SosInitial event, Emitter<SosState> emit) async {
emit(SosLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(sosId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = SosModel.fromJson(
statusModelList,
);
emit(UpdateState(sensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
return;
}
}
void _onSearchFaq(SearchFaqEvent event, Emitter<SosState> emit) {
emit(SosLoadingState());
List<QuestionModel> _faqQuestions = faqQuestions.where((question) {
return question.question
.toLowerCase()
.contains(event.query.toLowerCase());
}).toList();
emit(FaqSearchState(filteredFaqQuestions: _faqQuestions));
}
void _changeName(ChangeNameEvent event, Emitter<SosState> emit) {
emit(SosLoadingState());
editName = event.value!;
if (editName) {
Future.delayed(const Duration(milliseconds: 500), () {
focusNode.requestFocus();
});
} else {
focusNode.unfocus();
}
emit(NameEditingState(editName: editName));
}
void _toggleLowBattery(
ToggleEnableAlarmEvent event, Emitter<SosState> emit) async {
@ -111,6 +113,16 @@ class SosBloc extends Bloc<SosEvent, SosState> {
try {
closingReminder = event.isClosingReminderEnabled;
emit(UpdateState(sensor: deviceStatus));
// API call to update the state, if necessary
// await DevicesAPI.controlDevice(
// DeviceControlModel(
// deviceId: sosId,
// code: 'closing_reminder',
// value: closingReminder,
// ),
// sosId,
// );
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
}
@ -131,7 +143,7 @@ class SosBloc extends Bloc<SosEvent, SosState> {
startTime: startTime.toString(),
endTime: endTime.toString(),
deviceUuid: sosId,
code: 'sos',
code: 'sossensor_state',
);
recordGroups = response;
emit(UpdateState(sensor: deviceStatus));
@ -142,211 +154,35 @@ class SosBloc extends Bloc<SosEvent, SosState> {
}
}
//========================= Device Info & Status =============================
// _listenToChanges() {
// try {
// DatabaseReference ref =
// FirebaseDatabase.instance.ref('device-status/$WLId');
// Stream<DatabaseEvent> stream = ref.onValue;
static String deviceName = '';
// stream.listen((DatabaseEvent event) async {
// if (_timer != null) {
// await Future.delayed(const Duration(seconds: 2));
// }
// Map<dynamic, dynamic> usersMap =
// event.snapshot.value as Map<dynamic, dynamic>;
// List<StatusModel> statusList = [];
fetchDeviceInfo(SosInitialDeviseInfo event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
var response = await DevicesAPI.getDeviceInfo(sosId);
deviceInfo = DeviceInfoModel.fromJson(response);
deviceName = deviceInfo.name;
emit(LoadingSosDeviceInfo(deviceInfo: deviceInfo));
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
}
}
// usersMap['status'].forEach((element) {
// statusList.add(StatusModel(code: element['code'], value: true));
// });
void _fetchStatus(SosInitial event, Emitter<SosState> emit) async {
emit(SosLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(sosId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = SosModel.fromJson(
statusModelList,
);
emit(UpdateState(sensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
return;
}
}
//========================= assign & unassign devise to room =============================
List<DeviceModel> allDevices = [];
List<SubSpaceModel> roomsList = [];
void _fetchRoomsAndDevices(
FetchRoomsEvent event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(const SosFailedState(errorMessage: 'Something went wrong'));
return;
}
}
String roomId = '';
SpaceModel unit =
SpaceModel(id: '', name: '', community: Community(uuid: '', name: ''));
String _selectedOption = '';
bool _hasSelectionChanged = false;
void _onOptionSelected(SelectOptionEvent event, Emitter<SosState> emit) {
emit(SosLoadingState());
_selectedOption = event.selectedOption;
_hasSelectionChanged = true;
emit(OptionSelectedState(
selectedOption: _selectedOption,
hasSelectionChanged: _hasSelectionChanged));
}
void _onSaveSelection(SaveSelectionEvent event, Emitter<SosState> emit) {
if (_hasSelectionChanged) {
_hasSelectionChanged = false;
add(AssignRoomEvent(roomId: roomId, unit: unit, context: event.context));
emit(SaveSelectionSuccessState());
var cubit = HomeCubit.getInstance();
cubit.updatePageIndex(1);
Navigator.pushReplacementNamed(event.context, Routes.homeRoute);
}
}
void _assignDevice(AssignRoomEvent event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
await HomeManagementAPI.assignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, sosId);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
List<String> allDevicesIds = [];
allDevices.forEach((element) {
allDevicesIds.add(element.uuid!);
});
await HomeCubit.getInstance().fetchUnitsByUserId();
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveSelectionSuccessState());
} catch (e) {
emit(const SosFailedState(errorMessage: 'Something went wrong'));
return;
}
}
void _unassignDevice(UnassignRoomEvent event, Emitter<SosState> emit) async {
try {
Map<String, bool> roomDevicesId = {};
emit(SosLoadingState());
await HomeManagementAPI.unAssignDeviceToRoom(
event.unit.community.uuid, event.unit.id, event.roomId, sosId);
final devicesList = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId);
List<String> allDevicesIds = [];
allDevices.forEach((element) {
allDevicesIds.add(element.uuid!);
});
devicesList.forEach((e) {
if (allDevicesIds.contains(e.uuid!)) {
roomDevicesId[e.uuid!] = true;
} else {
roomDevicesId[e.uuid!] = false;
}
});
} catch (e) {
emit(const SosFailedState(errorMessage: 'Something went wrong'));
return;
}
}
Map<String, List<DeviceModel>> devicesByRoom = {};
//======================= setting name ======================================
Future<void> saveName(SaveNameEvent event, Emitter<SosState> emit) async {
if (_validateInputs()) return;
try {
add(const ChangeNameEvent(value: false));
isSaving = true;
emit(SosLoadingState());
var response = await DevicesAPI.putDeviceName(
deviceId: sosId, deviceName: nameController.text);
add(SosInitialDeviseInfo());
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState());
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
} finally {
isSaving = false;
}
}
bool _validateInputs() {
final nameError = fullNameValidator(nameController.text);
if (nameError != null) {
CustomSnackBar.displaySnackBar(nameError);
return true;
}
return false;
}
String? fullNameValidator(String? value) {
if (value == null) return 'name is required';
final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim();
if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) {
return 'name must be between 2 and 30 characters long';
}
if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) {
return 'Only alphanumeric characters, space, dash and single quote are allowed';
}
return null;
}
void _changeName(ChangeNameEvent event, Emitter<SosState> emit) {
emit(SosLoadingState());
editName = event.value!;
if (editName) {
Future.delayed(const Duration(milliseconds: 500), () {
focusNode.requestFocus();
});
} else {
focusNode.unfocus();
}
emit(NameEditingState(editName: editName));
}
//============================== update setting ===============================
bool enableUpdate = false;
void _toggleUpdate(ToggleUpdateEvent event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
enableUpdate = event.isUpdateEnabled!;
emit(SaveState());
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
}
}
//============================ Question and faq ============================
// deviceStatus = WaterLeakModel.fromJson(statusList);
// if (!isClosed) {
// add(
// WaterLeakSwitch(switchD: deviceStatus.waterContactState),
// );
// }
// });
// } catch (_) {}
// }
// Demo list of FAQ questions using the QuestionModel class
final List<QuestionModel> faqQuestions = [
QuestionModel(
id: 1,
@ -378,45 +214,46 @@ class SosBloc extends Bloc<SosEvent, SosState> {
'Check the SOS battery at least once a month to ensure it is operational.',
),
];
Future<void> _onSosInitial(
SosInitialQuestion event, Emitter<SosState> emit) async {
emit(SosLoadingState());
// SosModel sosModel = await fetchSosData(sosId); // Define this function as needed
emit(FaqLoadedState(filteredFaqQuestions: faqQuestions));
}
void _onSearchFaq(SearchFaqEvent event, Emitter<SosState> emit) {
emit(SosLoadingState());
List<QuestionModel> _faqQuestions = faqQuestions.where((question) {
return question.question
.toLowerCase()
.contains(event.query.toLowerCase());
}).toList();
emit(FaqSearchState(filteredFaqQuestions: _faqQuestions));
}
List<DeviceModel> allDevices = [];
List<SubSpaceModel> roomsList = [];
bool isHelpful = false;
void _toggleHelpful(ToggleHelpfulEvent event, Emitter<SosState> emit) async {
void _fetchRoomsAndDevices(
FetchRoomsEvent event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
isHelpful = event.isHelpful!;
emit(SaveState());
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
event.unit.community.uuid, event.unit.id);
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
emit(const SosFailedState(errorMessage: 'Something went wrong'));
return;
}
}
//===================== delete Device ===================================
String _selectedOption = '';
bool _hasSelectionChanged = false;
deleteDevice(DeleteDeviceEvent event, Emitter<SosState> emit) async {
try {
emit(SosLoadingState());
var response = await DevicesAPI.resetDevise(devicesUuid: sosId);
add(SosInitialDeviseInfo());
add(const SosInitial());
CustomSnackBar.displaySnackBar('Reset Successfully');
} catch (e) {
emit(SosFailedState(errorMessage: e.toString()));
void _onOptionSelected(SelectOptionEvent event, Emitter<SosState> emit) {
emit(SosLoadingState());
_selectedOption = event.selectedOption;
_hasSelectionChanged = true;
emit(OptionSelectedState(
selectedOption: _selectedOption,
hasSelectionChanged: _hasSelectionChanged));
}
void _onSaveSelection(SaveSelectionEvent event, Emitter<SosState> emit) {
if (_hasSelectionChanged) {
print('Save button clicked with selected option: $_selectedOption');
_hasSelectionChanged = false;
emit(SaveSelectionSuccessState());
}
}
}

View File

@ -1,8 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
abstract class SosEvent extends Equatable {
const SosEvent();
@ -11,9 +8,20 @@ abstract class SosEvent extends Equatable {
List<Object> get props => [];
}
class DeleteDeviceEvent extends SosEvent {}
class SosLoading extends SosEvent {}
class SosInitialDeviseInfo extends SosEvent {}
class SosSwitch extends SosEvent {
final String switchD;
final String deviceId;
final String productId;
const SosSwitch(
{required this.switchD, this.deviceId = '', this.productId = ''});
@override
List<Object> get props => [switchD, deviceId, productId];
}
class SosUpdated extends SosEvent {}
class SosInitial extends SosEvent {
const SosInitial();
@ -23,6 +31,15 @@ class ReportLogsInitial extends SosEvent {
const ReportLogsInitial();
}
class SosChangeStatus extends SosEvent {}
class GetCounterEvent extends SosEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class ToggleEnableAlarmEvent extends SosEvent {
final bool isLowBatteryEnabled;
@ -41,7 +58,44 @@ class ToggleClosingReminderEvent extends SosEvent {
List<Object> get props => [isClosingReminderEnabled];
}
class SaveNameEvent extends SosEvent {}
class ToggleSosAlarmEvent extends SosEvent {
final bool isSosAlarmEnabled;
const ToggleSosAlarmEvent(this.isSosAlarmEnabled);
@override
List<Object> get props => [isSosAlarmEnabled];
}
class SetCounterValue extends SosEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends SosEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends SosEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends SosEvent {}
class OnClose extends SosEvent {}
class ChangeNameEvent extends SosEvent {
final bool? value;
@ -68,64 +122,8 @@ class FetchRoomsEvent extends SosEvent {
}
class SelectOptionEvent extends SosEvent {
dynamic selectedOption;
SelectOptionEvent({
this.selectedOption,
});
final String selectedOption;
SelectOptionEvent({required this.selectedOption});
}
class SaveSelectionEvent extends SosEvent {
BuildContext context;
SaveSelectionEvent({
required this.context,
});
}
class AssignRoomEvent extends SosEvent {
final String roomId;
final SpaceModel unit;
final BuildContext context;
const AssignRoomEvent({
required this.roomId,
required this.unit,
required this.context,
});
@override
List<Object> get props => [
roomId,
unit,
context,
];
}
class UnassignRoomEvent extends SosEvent {
final String roomId;
final String deviceId;
final SpaceModel unit;
const UnassignRoomEvent(
{required this.roomId, required this.deviceId, required this.unit});
@override
List<Object> get props => [roomId, unit];
}
class LoadingDeviceInfo extends SosEvent {
DeviceInfoModel deviceInfo;
LoadingDeviceInfo({required this.deviceInfo});
@override
List<Object> get props => [deviceInfo];
}
class ToggleUpdateEvent extends SosEvent {
final bool? isUpdateEnabled;
const ToggleUpdateEvent({this.isUpdateEnabled});
}
class ToggleHelpfulEvent extends SosEvent {
final bool? isHelpful;
const ToggleHelpfulEvent({this.isHelpful});
}
class SaveSelectionEvent extends SosEvent {}

View File

@ -1,5 +1,4 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
@ -12,15 +11,10 @@ class SosState extends Equatable {
List<Object> get props => [];
}
class SosInitialState extends SosState {}
class SosLoadingState extends SosState {}
class SaveState extends SosState {}
class LoadingSosDeviceInfo extends SosState {
final DeviceInfoModel? deviceInfo;
const LoadingSosDeviceInfo({this.deviceInfo});
}
class SosFailedState extends SosState {
final String errorMessage;

View File

@ -1,149 +0,0 @@
import 'dart:convert';
class DeviceInfoModel {
final int activeTime;
final String category;
final String categoryName;
final int createTime;
final String gatewayId;
final String icon;
final String ip;
final String lat;
final String localKey;
final String lon;
final String model;
final String name;
final String nodeId;
final bool online;
final String ownerId;
final String productName;
final bool sub;
final String timeZone;
final int updateTime;
final String uuid;
final String productUuid;
final String productType;
final String permissionType;
final String macAddress;
final Subspace subspace;
DeviceInfoModel({
required this.activeTime,
required this.category,
required this.categoryName,
required this.createTime,
required this.gatewayId,
required this.icon,
required this.ip,
required this.lat,
required this.localKey,
required this.lon,
required this.model,
required this.name,
required this.nodeId,
required this.online,
required this.ownerId,
required this.productName,
required this.sub,
required this.timeZone,
required this.updateTime,
required this.uuid,
required this.productUuid,
required this.productType,
required this.permissionType,
required this.macAddress,
required this.subspace,
});
factory DeviceInfoModel.fromJson(Map<String, dynamic> json) {
return DeviceInfoModel(
activeTime: json['activeTime'],
category: json['category'],
categoryName: json['categoryName'],
createTime: json['createTime'],
gatewayId: json['gatewayId'],
icon: json['icon'],
ip: json['ip'] ?? "",
lat: json['lat'],
localKey: json['localKey'],
lon: json['lon'],
model: json['model'],
name: json['name'],
nodeId: json['nodeId'],
online: json['online'],
ownerId: json['ownerId'],
productName: json['productName'],
sub: json['sub'],
timeZone: json['timeZone'],
updateTime: json['updateTime'],
uuid: json['uuid'],
productUuid: json['productUuid'],
productType: json['productType'],
permissionType: json['permissionType'],
macAddress: json['macAddress'],
subspace: Subspace.fromJson(json['subspace']),
);
}
Map<String, dynamic> toJson() {
return {
'activeTime': activeTime,
'category': category,
'categoryName': categoryName,
'createTime': createTime,
'gatewayId': gatewayId,
'icon': icon,
'ip': ip,
'lat': lat,
'localKey': localKey,
'lon': lon,
'model': model,
'name': name,
'nodeId': nodeId,
'online': online,
'ownerId': ownerId,
'productName': productName,
'sub': sub,
'timeZone': timeZone,
'updateTime': updateTime,
'uuid': uuid,
'productUuid': productUuid,
'productType': productType,
'permissionType': permissionType,
'macAddress': macAddress,
'subspace': subspace.toJson(),
};
}
}
class Subspace {
final String uuid;
final String createdAt;
final String updatedAt;
final String subspaceName;
Subspace({
required this.uuid,
required this.createdAt,
required this.updatedAt,
required this.subspaceName,
});
factory Subspace.fromJson(Map<String, dynamic> json) {
return Subspace(
uuid: json['uuid'],
createdAt: json['createdAt'],
updatedAt: json['updatedAt'],
subspaceName: json['subspaceName'],
);
}
Map<String, dynamic> toJson() {
return {
'uuid': uuid,
'createdAt': createdAt,
'updatedAt': updatedAt,
'subspaceName': subspaceName,
};
}
}

View File

@ -78,12 +78,8 @@ class DeviceModel {
tempIcon = Assets.waterLeakIcon;
} else if (type == DeviceType.PC) {
tempIcon = Assets.powerClampIcon;
} else if (type == DeviceType.FourScene) {
tempIcon = Assets.fourSceneHomeIcon;
} else if (type == DeviceType.SixScene) {
tempIcon = Assets.sixSceneHomeIcon;
} else if (type == DeviceType.SOS) {
tempIcon = Assets.sosHomeIcon;
tempIcon = Assets.sosDevice;
} else {
tempIcon = Assets.assetsIconsLogo;
}

View File

@ -1,52 +0,0 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class FourSceneModelState {
dynamic scene_1;
dynamic scene_2;
dynamic scene_3;
dynamic scene_4;
dynamic scene_id_group_id;
dynamic switch_backlight;
FourSceneModelState({
required this.scene_1,
required this.scene_2,
required this.scene_3,
required this.scene_4,
required this.scene_id_group_id,
required this.switch_backlight,
});
factory FourSceneModelState.fromJson(List<StatusModel> jsonList) {
late dynamic _scene_1;
late dynamic _scene_2;
late dynamic _scene_3;
late dynamic _scene_4;
late dynamic _scene_id_group_id;
late dynamic _switch_backlight;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'scene_1') {
_scene_1 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_2') {
_scene_2 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_3') {
_scene_3 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_4') {
_scene_4 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_id_group_id') {
_scene_id_group_id = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'switch_backlight') {
_switch_backlight = jsonList[i].value ?? false;
}
}
return FourSceneModelState(
scene_1: _scene_1,
scene_2: _scene_2,
scene_3: _scene_3,
scene_4: _scene_4,
scene_id_group_id: _scene_id_group_id,
switch_backlight: _switch_backlight,
);
}
}

View File

@ -1,85 +0,0 @@
class FourSceneSwitchModel {
final String switchName;
final DateTime createdAt;
final DateTime updatedAt;
final String deviceUuid;
final Scene scene;
FourSceneSwitchModel({
required this.switchName,
required this.createdAt,
required this.updatedAt,
required this.deviceUuid,
required this.scene,
});
factory FourSceneSwitchModel.fromJson(Map<String, dynamic> json) {
return FourSceneSwitchModel(
switchName: json['switchName'],
createdAt: DateTime.parse(json['createdAt']),
updatedAt: DateTime.parse(json['updatedAt']),
deviceUuid: json['deviceUuid'],
scene: Scene.fromJson(json['scene']),
);
}
}
class Scene {
final String uuid;
final String sceneTuyaId;
final String name;
final String status;
final String icon;
final String iconUuid;
final bool showInHome;
final String type;
final List<Action> actions;
Scene({
required this.uuid,
required this.sceneTuyaId,
required this.name,
required this.status,
required this.icon,
required this.iconUuid,
required this.showInHome,
required this.type,
required this.actions,
});
factory Scene.fromJson(Map<String, dynamic> json) {
return Scene(
uuid: json['uuid'],
sceneTuyaId: json['sceneTuyaId'],
name: json['name'],
status: json['status'],
icon: json['icon'],
iconUuid: json['iconUuid'],
showInHome: json['showInHome'],
type: json['type'],
actions: (json['actions'] as List)
.map((action) => Action.fromJson(action))
.toList(),
);
}
}
class Action {
final String actionExecutor;
final String entityId;
final Map<String, dynamic> executorProperty;
Action({
required this.actionExecutor,
required this.entityId,
required this.executorProperty,
});
factory Action.fromJson(Map<String, dynamic> json) {
return Action(
actionExecutor: json['actionExecutor'],
entityId: json['entityId'],
executorProperty: json['executorProperty'],
);
}
}

View File

@ -1,6 +0,0 @@
class GroupDevicesModel {
String? icon;
final String? name;
final String? dec;
GroupDevicesModel({this.icon, this.name, this.dec});
}

View File

@ -1,64 +0,0 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class SixSceneModel {
dynamic scene_1;
dynamic scene_2;
dynamic scene_3;
dynamic scene_4;
dynamic scene_5;
dynamic scene_6;
dynamic scene_id_group_id;
dynamic switch_backlight;
SixSceneModel({
required this.scene_1,
required this.scene_2,
required this.scene_3,
required this.scene_4,
required this.scene_5,
required this.scene_6,
required this.scene_id_group_id,
required this.switch_backlight,
});
factory SixSceneModel.fromJson(List<StatusModel> jsonList) {
late dynamic _scene_1;
late dynamic _scene_2;
late dynamic _scene_3;
late dynamic _scene_4;
late dynamic _scene_5;
late dynamic _scene_6;
late dynamic _scene_id_group_id;
late dynamic _switch_backlight;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'scene_1') {
_scene_1 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_2') {
_scene_2 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_3') {
_scene_3 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_4') {
_scene_4 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_5') {
_scene_5 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_6') {
_scene_6 = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'scene_id_group_id') {
_scene_id_group_id = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'switch_backlight') {
_switch_backlight = jsonList[i].value ?? false;
}
}
return SixSceneModel(
scene_1: _scene_1,
scene_2: _scene_2,
scene_3: _scene_3,
scene_4: _scene_4,
scene_5: _scene_5,
scene_6: _scene_6,
scene_id_group_id: _scene_id_group_id,
switch_backlight: _switch_backlight,
);
}
}

View File

@ -1,11 +0,0 @@
class SixSceneQuestionModel {
final int id;
final String question;
final String answer;
SixSceneQuestionModel({
required this.id,
required this.question,
required this.answer,
});
}

View File

@ -1,200 +0,0 @@
// import 'package:flutter/material.dart';
// import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:flutter_svg/svg.dart';
// import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart';
// import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart';
// import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart';
// import 'package:syncrow_app/features/devices/model/device_model.dart';
// import 'package:syncrow_app/features/shared_widgets/default_container.dart';
// import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
// import 'package:syncrow_app/generated/assets.dart';
// import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
// class FourSceneCreateGroup extends StatelessWidget {
// final DeviceModel? device;
// const FourSceneCreateGroup({super.key, this.device});
// @override
// Widget build(BuildContext context) {
// return DefaultScaffold(
// title: 'Create Group',
// child: BlocProvider(
// create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '')
// ..add(const FourSceneInitial()),
// child: BlocBuilder<FourSceneBloc, FourSceneState>(
// builder: (context, state) {
// final sensor = BlocProvider.of<FourSceneBloc>(context);
// return state is LoadingNewSate
// ? const Center(
// child: DefaultContainer(
// width: 50,
// height: 50,
// child: CircularProgressIndicator()),
// )
// : Padding(
// padding: const EdgeInsets.all(8.0),
// child: Column(
// children: [
// const Padding(
// padding: EdgeInsets.only(left: 25, right: 25),
// child: BodySmall(
// text:
// 'Devices in the same group can be controlled together',
// fontColor: ColorsManager.primaryTextColor,
// textAlign: TextAlign.center,
// ),
// ),
// Flexible(
// child: ListView.builder(
// itemCount: sensor.groupDevices.length,
// itemBuilder: (context, index) {
// return InkWell(
// onTap: () {
// BlocProvider.of<FourSceneBloc>(context).add(
// RemoveDeviceFromGroup(
// sensor.groupDevices[index],
// Assets.addDevicesIcon));
// },
// child: DefaultContainer(
// child: Padding(
// padding: const EdgeInsets.all(5.0),
// child: Row(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Row(
// children: [
// SvgPicture.asset(
// sensor.groupDevices[index].icon!,
// fit: BoxFit.contain,
// ),
// const SizedBox(
// width: 15,
// ),
// BodyMedium(
// text: sensor
// .groupDevices[index].name!,
// fontColor:
// ColorsManager.primaryTextColor,
// textAlign: TextAlign.center,
// fontSize: 15,
// ),
// ],
// ),
// BodyMedium(
// text: sensor.groupDevices[index].dec!,
// fontColor: ColorsManager.grayColor,
// textAlign: TextAlign.center,
// fontSize: 15,
// ),
// ],
// ),
// )),
// );
// },
// ),
// ),
// Flexible(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const BodyLarge(
// text: 'Devices to be added',
// fontColor: ColorsManager.grayColor,
// textAlign: TextAlign.center,
// fontSize: 12,
// fontWeight: FontWeight.w700,
// ),
// const SizedBox(
// height: 5,
// ),
// sensor.devices.isNotEmpty
// ? Expanded(
// child: ListView.builder(
// itemCount: sensor.devices.length,
// itemBuilder: (context, index) {
// final device = sensor.devices[index];
// return GestureDetector(
// onTap: () {
// BlocProvider.of<FourSceneBloc>(
// context)
// .add(AddDeviceToGroup(device,
// Assets.minusIcon));
// },
// child: DefaultContainer(
// child: Padding(
// padding:
// const EdgeInsets.all(5.0),
// child: Row(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// mainAxisAlignment:
// MainAxisAlignment
// .spaceBetween,
// children: [
// Row(
// children: [
// SvgPicture.asset(
// device.icon!,
// fit: BoxFit.contain,
// ),
// const SizedBox(
// width: 15,
// ),
// BodyMedium(
// text: device.name!,
// fontColor: ColorsManager
// .primaryTextColor,
// textAlign:
// TextAlign.center,
// fontSize: 15,
// ),
// ],
// ),
// BodyMedium(
// text: device.dec!,
// fontColor: ColorsManager
// .grayColor,
// textAlign:
// TextAlign.center,
// fontSize: 15,
// ),
// ],
// ),
// ),
// ),
// );
// },
// ),
// )
// : const Column(
// children: [
// BodySmall(
// text:
// 'Currently no devices available to create group',
// fontColor: ColorsManager.grayColor,
// textAlign: TextAlign.center,
// fontSize: 12,
// fontWeight: FontWeight.w400,
// ),
// ],
// ),
// ],
// ),
// ),
// const Spacer()
// ],
// ),
// );
// },
// ),
// ),
// );
// }
// }

View File

@ -1,154 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/question_page.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class FaqSettingPage extends StatelessWidget {
final DeviceModel? device;
const FaqSettingPage({super.key, this.device});
@override
Widget build(BuildContext context) {
TextEditingController _searchController = TextEditingController();
return DefaultScaffold(
title: 'FAQ',
child: BlocProvider(
create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '')
..add(const DeviceSettingInitialQuestion()),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) {
final sensor = BlocProvider.of<DeviceSettingBloc>(context);
List<QuestionModel> displayedQuestions = [];
if (state is FaqSearchState) {
displayedQuestions = state.filteredFaqQuestions;
} else if (state is FaqLoadedState) {
displayedQuestions = state.filteredFaqQuestions;
}
return state is DeviceSettingLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
DefaultContainer(
padding: const EdgeInsets.all(5),
child: TextFormField(
controller: _searchController,
onChanged: (value) {
sensor.add(SearchFaqEvent(value));
},
decoration: InputDecoration(
hintText: 'Enter your questions',
hintStyle: const TextStyle(
color: ColorsManager.textGray,
fontSize: 16,
fontWeight: FontWeight.w400),
suffixIcon: Container(
padding: const EdgeInsets.all(5.0),
margin: const EdgeInsets.all(10.0),
child: SvgPicture.asset(
Assets.searchIcon,
fit: BoxFit.contain,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.04,
),
BodyMedium(
text: _searchController.text.isEmpty
? 'Device Related FAQs'
: '${displayedQuestions.length} Help Topics',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
const SizedBox(
height: 8,
),
displayedQuestions.isEmpty
? const SizedBox()
: DefaultContainer(
child: ListView.builder(
shrinkWrap: true,
itemCount: displayedQuestions.length,
itemBuilder: (context, index) {
final faq = displayedQuestions[index];
return InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
QuestionPageSetting(
deviceId: device!.uuid,
questionModel: faq,
)),
);
},
child: SizedBox(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: BodyMedium(
fontSize: 14,
fontWeight: FontWeight.w400,
text: faq.question,
),
),
const Icon(
Icons.keyboard_arrow_right,
color: ColorsManager.textGray,
),
],
),
),
if (index !=
displayedQuestions.length -
1) // Exclude divider for the last item
const Divider(
color: ColorsManager.dividerColor,
),
],
),
),
);
},
)),
],
);
},
),
),
);
}
}

View File

@ -1,210 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class LocationSettingPage extends StatelessWidget {
final SpaceModel? space;
final String? deviceId;
const LocationSettingPage({
super.key,
this.space,
this.deviceId,
});
@override
Widget build(BuildContext context) {
String roomIdSelected = '';
return Scaffold(
body: BlocProvider(
create: (context) => DeviceSettingBloc(deviceId: deviceId ?? '')
..add(const DeviceSettingInitial())
..add(const DeviceSettingInitialInfo())
..add(FetchRoomsEvent(unit: space!)),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) {
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
if (state is SaveSelectionSuccessState) {
Future.delayed(const Duration(microseconds: 500), () {
_bloc.add(const DeviceSettingInitialInfo());
Navigator.of(context).pop(true);
});
}
return state is DeviceSettingLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
)
: DefaultScaffold(
actions: [
BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) {
final bool canSave = state is OptionSelectedState &&
state.hasSelectionChanged;
return InkWell(
onTap: canSave
? () {
context.read<DeviceSettingBloc>().add(
AssignRoomEvent(
context: context,
roomId: roomIdSelected,
unit: space!));
}
: null,
child: BodyMedium(
text: 'Save',
fontWeight: FontWeight.w700,
fontSize: 16,
fontColor: canSave
? ColorsManager.slidingBlueColor
: ColorsManager.primaryTextColor,
),
);
},
),
const SizedBox(width: 20),
],
child: ListView(
shrinkWrap: true,
padding: const EdgeInsets.symmetric(vertical: 20),
children: [
const BodyMedium(
text: 'Smart Device Location',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
const SizedBox(height: 5),
DefaultContainer(
padding: const EdgeInsets.all(20),
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: _bloc.roomsList.length,
itemBuilder: (context, index) {
final fromRoom = _bloc.roomsList[index];
final isSelected = (state
is OptionSelectedState &&
state.selectedOption == fromRoom.id) ||
(state is! OptionSelectedState &&
fromRoom.id ==
_bloc.deviceInfo.subspace.uuid);
return Column(
children: [
_buildCheckboxOption(
label: fromRoom.name!,
isSelected: isSelected,
onTap: (label) {
context.read<DeviceSettingBloc>().add(
SelectOptionEvent(
selectedOption: fromRoom.id!,
),
);
roomIdSelected = fromRoom.id!;
},
),
if (index < _bloc.roomsList.length - 1) ...[
const SizedBox(height: 10),
const Divider(
color: ColorsManager.dividerColor,
),
const SizedBox(height: 10),
],
],
);
},
),
),
],
),
);
},
),
),
);
}
}
class CircularCheckbox extends StatefulWidget {
final bool value;
final ValueChanged<bool?> onChanged;
const CircularCheckbox(
{super.key, required this.value, required this.onChanged});
@override
_CircularCheckboxState createState() => _CircularCheckboxState();
}
class _CircularCheckboxState extends State<CircularCheckbox> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
widget.onChanged(!widget.value);
},
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: widget.value
? ColorsManager.primaryColorWithOpacity.withOpacity(0.01)
: Colors.grey,
width: 2.0,
),
color: widget.value
? ColorsManager.primaryColorWithOpacity
: Colors.transparent,
),
width: 24.0,
height: 24.0,
child: widget.value
? const Icon(
Icons.check,
color: Colors.white,
size: 16.0,
)
: null,
),
);
}
}
Widget _buildCheckboxOption({
required String label,
required bool isSelected,
required Function(String) onTap,
}) {
return Padding(
padding: const EdgeInsets.only(bottom: 10, top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BodyMedium(
text: label,
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w400),
),
CircularCheckbox(
value: isSelected,
onChanged: (bool? value) {
if (value == true) {
onTap(label);
}
},
),
],
),
);
}

View File

@ -1,142 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class QuestionPageSetting extends StatelessWidget {
final QuestionModel? questionModel;
final String? deviceId;
const QuestionPageSetting({super.key, this.questionModel, this.deviceId});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'FAQ',
child: BlocProvider(
create: (context) => DeviceSettingBloc(deviceId: deviceId!)
..add(const DeviceSettingInitial()),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) {
final sensor = BlocProvider.of<DeviceSettingBloc>(context);
return state is DeviceSettingLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: Column(
children: [
DefaultContainer(
padding: const EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BodyLarge(
text: questionModel!.question,
fontSize: 22,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
const SizedBox(
height: 15,
),
BodyMedium(
text: questionModel!.answer,
fontSize: 14,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.secondaryTextColor,
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.15,
),
Center(
child: SizedBox(
width: 180,
child: DefaultButton(
backgroundColor: sensor.isHelpful == true
? ColorsManager.grayColor
: ColorsManager.grayButtonColors,
borderRadius: 50,
onPressed: () {
sensor.add(
const ToggleHelpfulEvent(isHelpful: true));
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.thumbUp,
fit: BoxFit.fill,
),
const SizedBox(
width: 10,
),
const BodyMedium(
text: 'Helpful',
fontSize: 12,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
],
)),
),
),
const SizedBox(
height: 15,
),
Center(
child: SizedBox(
width: 180,
child: DefaultButton(
backgroundColor: sensor.isHelpful == false
? ColorsManager.grayColor
: ColorsManager.grayButtonColors,
borderRadius: 50,
onPressed: () {
sensor.add(
const ToggleHelpfulEvent(isHelpful: false));
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.thumbDown,
fit: BoxFit.fill,
),
const SizedBox(
width: 10,
),
const BodyMedium(
text: 'Not Helpful',
fontSize: 12,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
],
)),
),
),
],
);
},
),
),
);
}
}

View File

@ -1,451 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/faq_page.dart';
import 'package:syncrow_app/features/devices/view/device_settings/info_page.dart';
import 'package:syncrow_app/features/devices/view/device_settings/profile_page.dart';
import 'package:syncrow_app/features/devices/view/device_settings/share_Device_page.dart';
import 'package:syncrow_app/features/devices/view/device_settings/update_dialog.dart';
import 'package:syncrow_app/features/devices/view/device_settings/update_page.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/delete_device_dialogs.dart';
import 'package:syncrow_app/features/shared_widgets/setting_widget.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SettingsPage extends StatelessWidget {
final DeviceModel? device;
const SettingsPage({super.key, this.device});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Device Settings',
child: BlocProvider(
create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '')
..add(const DeviceSettingInitial())
..add(const DeviceSettingInitialInfo()),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) {
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
return state is DeviceSettingLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: ListView(
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: InkWell(
onTap: () async {
bool val = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SettingProfilePage(
device: device,
),
),
);
if (val == true) {
_bloc.add(const DeviceSettingInitialInfo());
}
},
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
DefaultContainer(
borderRadius: const BorderRadius.all(
Radius.circular(30)),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Padding(
padding:
const EdgeInsets.only(left: 90),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
SizedBox(
child: Text(
_bloc.deviceInfo.name,
style: const TextStyle(
fontSize: 16,
fontWeight:
FontWeight.w700,
color: ColorsManager
.grayColor,
),
overflow: TextOverflow
.ellipsis, // Adds ellipsis (...) when the text overflows.
maxLines:
1, // Restricts the text to a single line.
)),
const SizedBox(
height: 5,
),
BodySmall(
text: _bloc
.deviceInfo
.subspace
.subspaceName),
],
),
),
SvgPicture.asset(
Assets.editNameSetting,
fit: BoxFit.contain,
height: 30,
),
],
),
),
),
),
],
),
Positioned(
top: 0,
left: 20,
child: CircleAvatar(
radius: 43,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 40,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 40,
backgroundColor:
ColorsManager.backgroundColor,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
device!.type == "SOS"
? ClipOval(
child: SvgPicture.asset(
Assets.sosHomeIcon,
fit: BoxFit.contain,
height: 70,
),
)
: Padding(
padding: device!.type ==
"4S"
? const EdgeInsets.only(
top: 5)
: const EdgeInsets.only(
top: 0),
child: SizedBox(
height: 70,
child: SvgPicture.asset(
device!.type == "4S"
? Assets
.fourSceneIcon
: Assets
.sixSceneIcon,
fit: BoxFit.contain,
),
),
),
],
),
),
)),
),
],
),
),
),
const SizedBox(height: 20),
const BodyMedium(
text: 'Device Management',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
DefaultContainer(
child: Column(
children: [
SettingWidget(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SettingInfoPage(
device: device!,
)),
);
},
text: 'Device Information',
icon: Assets.infoIcon,
),
// const Divider(
// color: ColorsManager.dividerColor,
// ),
// SettingWidget(
// onTap: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) =>
// ShareFourScenePage(
// device: device!)),
// );
// },
// text: 'Tap-to Run and Automation',
// icon: Assets.tapRunIcon,
// ),
],
),
),
const SizedBox(height: 20),
const BodyMedium(
text: 'Device Offline Notification',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
DefaultContainer(
child: Column(
children: [
SettingWidget(
value: _bloc.enableAlarm,
onChanged: (p0) {
context
.read<DeviceSettingBloc>()
.add(ToggleEnableAlarmEvent(p0));
},
isNotification: true,
onTap: () {},
text: 'Offline Notification',
icon: Assets.notificationIcon,
),
],
),
),
const SizedBox(height: 20),
const BodyMedium(
text: 'Others',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
const SizedBox(height: 5),
DefaultContainer(
child: Column(
children: [
SettingWidget(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
ShareDevicePage(device: device!)),
);
},
text: 'Share Device',
icon: Assets.shareIcon,
),
// const Divider(
// color: ColorsManager.dividerColor,
// ),
// SettingWidget(
// onTap: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) =>
// FourSceneCreateGroup(
// device: device!)),
// );
// },
// text: 'Create Group',
// icon: Assets.createGroupIcon,
// ),
const Divider(
color: ColorsManager.dividerColor,
),
SettingWidget(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
FaqSettingPage(device: device!)),
);
},
text: 'Device FAQ',
icon: Assets.faqIcon,
),
const Divider(
color: ColorsManager.dividerColor,
),
SettingWidget(
onTapUpdate: () {
showDialog(
context: context,
builder: (context) {
return UpdateInfoDialog(
cancelTab: () {
Navigator.of(context).pop();
},
confirmTab: () {
Navigator.of(context).pop();
},
);
},
);
},
isUpdate: true,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
const UpdatePageSetting()),
);
},
text: 'Device Update',
icon: Assets.updateIcon,
),
],
),
),
const SizedBox(height: 20),
InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodyMedium(
text: 'Remove Device',
fontWeight: FontWeight.w700,
fontSize: 16,
fontColor: ColorsManager.red,
),
const SizedBox(height: 10),
const SizedBox(
width: 250,
child: Divider(
color: ColorsManager.dividerColor,
),
),
const SizedBox(height: 10),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
showDialog(
context: context,
builder: (context) {
return DisconnectDeviceDialog(
cancelTab: () {
Navigator.of(context).pop();
},
confirmTab: () {
Navigator.of(context).pop();
},
);
},
);
},
child: const BodyMedium(
text: 'Disconnect Device',
fontWeight: FontWeight.w400,
fontSize: 15,
fontColor:
ColorsManager.textPrimaryColor,
),
),
const Icon(
Icons.keyboard_arrow_right,
color: ColorsManager.textGray,
)
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
showDialog(
context: context,
builder: (context) {
return DisconnectWipeData(
cancelTab: () {
Navigator.of(context).pop();
},
confirmTab: () {
_bloc.add(
DeleteDeviceEvent());
},
);
},
);
},
child: const BodyMedium(
text:
'Disconnect Device and Wipe Data',
fontWeight: FontWeight.w400,
fontSize: 15,
fontColor:
ColorsManager.textPrimaryColor,
),
),
const Icon(
Icons.keyboard_arrow_right,
color: ColorsManager.textGray,
)
],
),
],
),
);
},
);
},
child: const Center(
child: BodyMedium(
text: 'Remove Device',
fontWeight: FontWeight.w400,
fontSize: 15,
fontColor: ColorsManager.red,
),
),
),
],
);
},
),
),
);
}
}

View File

@ -1,327 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart';
import 'package:syncrow_app/features/devices/view/widgets/restart_status_dialog.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SixSelectSceneFourPage extends StatelessWidget {
final String? switchSelected;
final String? deviceId;
SixSelectSceneFourPage({super.key, this.switchSelected, this.deviceId});
final TextEditingController _searchController = TextEditingController();
final int? selectedSwitchIndex = 0;
final spaces = HomeCubit.getInstance().spaces;
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => SixSceneBloc(sixSceneId: deviceId!)
..add(LoadScenes(
unit: spaces!.first,
unitId: spaces!.first.id,
showInDevice: false,
))
..add(GetSceneBySwitchName(switchName: switchSelected)),
child: BlocBuilder<SixSceneBloc, SixSceneState>(
builder: (context, state) {
final sensorBloc = BlocProvider.of<SixSceneBloc>(context);
if (state is SaveSelectionSuccessState) {
Future.delayed(const Duration(milliseconds: 250), () {
Navigator.of(context).pop(true);
Navigator.of(context).pop(true);
});
}
return DefaultScaffold(
title: 'Select Scene',
actions: [_buildSaveButton(context, state, sensorBloc)],
child: _buildSceneContent(context, sensorBloc, state),
);
},
),
);
}
// Save button builder
Widget _buildSaveButton(
BuildContext context, SixSceneState state, SixSceneBloc sensorBloc) {
final bool canSave = state is SceneSelectionUpdatedState;
return GestureDetector(
onTap: canSave
? () {
context.read<SixSceneBloc>().add(AssignDeviceScene(
sceneUuid: sensorBloc.selectedSceneId,
switchName: switchSelected,
unit: spaces!.first));
}
: null,
child: Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: BodyMedium(
text: 'Save',
fontWeight: FontWeight.w700,
fontSize: 16,
fontColor: canSave
? ColorsManager.slidingBlueColor
: ColorsManager.primaryTextColor,
),
),
);
}
// Loading indicator
Widget _buildLoadingIndicator() {
return const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
);
}
// Main scene content with search bar and grid
Widget _buildSceneContent(
BuildContext context, SixSceneBloc sensorBloc, SixSceneState state) {
return Column(
children: [
_buildSearchBar(sensorBloc),
const SizedBox(height: 20),
Expanded(
child: state is SixSceneLoadingState
? _buildLoadingIndicator()
: sensorBloc.filteredScenes.isEmpty
? const Center(
child: SizedBox(
child: BodySmall(text: 'No Scenes available'),
),
)
: _buildSceneGrid(sensorBloc, state),
),
],
);
}
// Search bar widget
Widget _buildSearchBar(SixSceneBloc sensorBloc) {
return TextFormField(
controller: _searchController,
onChanged: (value) {
sensorBloc.add(SearchScenesEvent(query: value));
},
decoration: InputDecoration(
hintText: 'Search',
hintStyle: const TextStyle(
color: ColorsManager.textGray,
fontSize: 16,
fontWeight: FontWeight.w400),
suffixIcon: Container(
padding: const EdgeInsets.all(5.0),
margin: const EdgeInsets.all(10.0),
child: SvgPicture.asset(
Assets.searchIcon,
fit: BoxFit.contain,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
);
}
// Scene grid builder
Widget _buildSceneGrid(SixSceneBloc sensorBloc, SixSceneState state) {
final scenes = sensorBloc.filteredScenes;
return GridView.builder(
itemCount: scenes.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
mainAxisExtent: 120,
),
itemBuilder: (context, index) {
final scene = scenes[index];
bool isSelected = scene.id ==
(state is SceneSelectionUpdatedState
? state.selectedSceneId
: sensorBloc.selectedFormApiSceneId);
return SceneItem(
id: scene.id,
value: isSelected,
disablePlayButton: false,
onChanged: (isSelected) {
sensorBloc.add(SelectOptionEvent(selectedOption: scene.id));
sensorBloc.add(SelectSceneEvent(
selectedSceneId: scene.id, isSelected: isSelected));
},
icon: scene.iconInBytes,
title: scene.name,
);
// if (index == scenes.length) {
// return InkWell(
// onTap: () => Navigator.pushNamed(
// NavigationService.navigatorKey.currentContext!,
// Routes.sceneTasksRoute,
// arguments: SceneSettingsRouteArguments(
// sceneType: '',
// sceneId: '',
// sceneName: '',
// ),
// ),
// child: CreateSceneItem(),
// );
// } else {
// final scene = scenes[index];
// bool isSelected = scene.id ==
// (state is SceneSelectionUpdatedState
// ? state.selectedSceneId
// : sensorBloc.selectedFormApiSceneId);
// return SceneItem(
// id: scene.id,
// value: isSelected,
// disablePlayButton: false,
// onChanged: (isSelected) {
// sensorBloc.add(SelectOptionEvent(selectedOption: scene.id));
// sensorBloc.add(SelectSceneEvent(unitId: scene.id));
// },
// icon: scene.iconInBytes,
// title: scene.name,
// );
// }
},
);
}
}
class SceneItem extends StatelessWidget {
final String id;
final Uint8List icon;
final String title;
final bool disablePlayButton;
final bool value;
final Function(bool) onChanged;
const SceneItem({
required this.id,
required this.icon,
required this.title,
this.disablePlayButton = false,
required this.value,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 2,
spreadRadius: 1,
offset: Offset(0, 3),
),
],
),
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (!disablePlayButton)
Image.memory(
icon,
height: 32,
width: 32,
fit: BoxFit.fill,
errorBuilder: (context, error, stackTrace) => Image.asset(
Assets.assetsIconsLogo,
height: 32,
width: 32,
fit: BoxFit.fill),
),
],
),
CircularCheckbox(
value: value,
onChanged: (isSelected) => onChanged(isSelected!),
),
],
),
BodyMedium(
text: title,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w700,
color: ColorsManager.secondaryTextColor),
textAlign: TextAlign.center,
),
],
),
);
}
}
// Widget for the static "Create Scene" button
class CreateSceneItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 5,
spreadRadius: 2,
offset: Offset(0, 3),
),
],
),
padding: const EdgeInsets.all(16),
child: const Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.add_circle,
color: ColorsManager.grayButtonColors, size: 36),
BodyMedium(
text: 'Create Scene',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: ColorsManager.secondaryTextColor),
textAlign: TextAlign.center,
),
],
),
);
}
}

View File

@ -1,177 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_switches_card.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
// ignore: must_be_immutable
class SelectSwitchDialog extends StatefulWidget {
final Function()? cancelTab;
final Function(String)? confirmTab;
String? switch1Title;
String? switch2Title;
String? switch3Title;
String? switch4Title;
String? switch5Title;
String? switch6Title;
SelectSwitchDialog(
{super.key,
required this.cancelTab,
required this.confirmTab,
this.switch1Title,
this.switch2Title,
this.switch3Title,
this.switch4Title,
this.switch5Title,
this.switch6Title});
@override
State<SelectSwitchDialog> createState() => _SelectSwitchDialogState();
}
class _SelectSwitchDialogState extends State<SelectSwitchDialog> {
String selectedSwitchName = '';
@override
Widget build(BuildContext context) {
return AlertDialog(
backgroundColor: ColorsManager.onPrimaryColor,
contentPadding: EdgeInsets.zero,
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const SizedBox(height: 10),
const BodyLarge(
text: 'Select Switch',
fontWeight: FontWeight.w700,
fontColor: ColorsManager.primaryColor,
fontSize: 16,
),
const Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Divider(color: ColorsManager.textGray),
),
const SizedBox(height: 20),
Row(
children: [
SixSwitchsCardDialog(
switch1Title: widget.switch1Title,
switch2Title: widget.switch2Title,
switch3Title: widget.switch3Title,
switch4Title: widget.switch4Title,
switch5Title: widget.switch5Title,
switch6Title: widget.switch6Title,
switch1Down: selectedSwitchName == 'scene_4'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch1Up: selectedSwitchName == 'scene_1'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch2Down: selectedSwitchName == 'scene_5'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch2Up: selectedSwitchName == 'scene_2'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch3Up: selectedSwitchName == 'scene_3'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch3Down: selectedSwitchName == 'scene_6'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
onSwitch3DownTap: () {
setState(() => selectedSwitchName = 'scene_3');
},
onSwitch3UpTap: () {
setState(() => selectedSwitchName = 'scene_6');
},
onSwitch1UpTap: () {
setState(() => selectedSwitchName = 'scene_1');
},
onSwitch1DownTap: () {
setState(() => selectedSwitchName = 'scene_4');
},
onSwitch2UpTap: () {
setState(() => selectedSwitchName = 'scene_5');
},
onSwitch2DownTap: () {
setState(() => selectedSwitchName = 'scene_2');
},
),
],
),
const SizedBox(height: 20),
const Padding(
padding: EdgeInsets.only(bottom: 15, left: 5, right: 5, top: 10),
child: Center(
child: Text(
'Please select one of the switches available to continue',
textAlign: TextAlign.center,
),
),
),
Row(
children: [
Expanded(
child: Container(
decoration: const BoxDecoration(
border: Border(
right:
BorderSide(color: ColorsManager.textGray, width: 0.5),
top: BorderSide(color: ColorsManager.textGray, width: 1.0),
)),
child: SizedBox(
child: InkWell(
onTap: widget.cancelTab,
child: const Padding(
padding: EdgeInsets.all(15),
child: Center(
child: Text(
'Cancel',
style: TextStyle(
color: ColorsManager.textPrimaryColor,
fontSize: 14,
fontWeight: FontWeight.w400),
),
),
),
),
),
),
),
Expanded(
child: Container(
decoration: const BoxDecoration(
border: Border(
left: BorderSide(color: ColorsManager.textGray, width: 0.5),
top: BorderSide(color: ColorsManager.textGray, width: 1.0),
)),
child: InkWell(
onTap: selectedSwitchName == ''
? () {}
: () => widget.confirmTab!(selectedSwitchName),
child: Padding(
padding: EdgeInsets.all(15),
child: Center(
child: Text(
'Next',
style: TextStyle(
color: selectedSwitchName == ''
? ColorsManager.textPrimaryColor
.withOpacity(0.6)
: ColorsManager.primaryColor,
fontSize: 14,
fontWeight: FontWeight.w400),
),
),
),
),
),
),
],
)
],
),
);
}
}

View File

@ -1,248 +0,0 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/six_scene_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_scene_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart';
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_switches_card.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
class SixSceneScreen extends StatelessWidget {
final DeviceModel? device;
const SixSceneScreen({super.key, this.device});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '')
..add(const SixSceneInitial())
..add(const SixSceneInitialInfo())
..add(const SexSceneSwitchInitial()),
child: BlocBuilder<SixSceneBloc, SixSceneState>(
builder: (context, state) {
final _bloc = BlocProvider.of<SixSceneBloc>(context);
SixSceneModel model = SixSceneModel(
scene_1: '',
scene_2: '',
scene_3: '',
scene_4: '',
scene_5: '',
scene_6: '',
scene_id_group_id: '',
switch_backlight: '',
);
if (state is LoadingNewSate) {
model = state.device;
} else if (state is UpdateState) {
model = state.device;
}
return DefaultScaffold(
title: _bloc.deviceInfo.name,
actions: [
InkWell(
onTap: () async {
var val = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SettingsPage(device: device!),
),
);
if (val == null) {
_bloc.add(const SixSceneInitialInfo());
_bloc.add(const SixSceneInitial());
_bloc.add(const SexSceneSwitchInitial());
}
},
child: SvgPicture.asset(Assets.assetsIconsSettings),
),
const SizedBox(width: 10),
],
child: state is SixSceneLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
)
: RefreshIndicator(
onRefresh: () async {
_bloc.add(const SixSceneInitial());
},
child: ListView(
children: [
SizedBox(
height: MediaQuery.sizeOf(context).height * 0.8,
child: Column(
children: [
SixSwitchsCardDialog(
switch1Title: model.scene_1,
switch2Title: model.scene_2,
switch3Title: model.scene_3,
switch4Title: model.scene_4,
switch5Title: model.scene_5,
switch6Title: model.scene_6,
switch1Down: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch1Up: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch2Down: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch2Up: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch3Up: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch3Down: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
onSwitch3DownTap: () {
debugPrint("onSwitch3DownTap");
},
onSwitch3UpTap: () {
debugPrint("onSwitch3UpTap");
},
onSwitch1UpTap: () {
debugPrint("Switch 1 Up tapped");
},
onSwitch1DownTap: () {
debugPrint("Switch 1 Down tapped");
},
onSwitch2UpTap: () {
debugPrint("Switch 2 Up tapped");
},
onSwitch2DownTap: () {
debugPrint("Switch 2 Down tapped");
},
),
Flexible(
child: Row(
children: [
Expanded(
child: DefaultContainer(
onTap: () {
_bloc.add(ChangeSwitchStatusEvent());
},
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46,
maxWidth: 50,
),
child: SvgPicture.asset(
Assets.backlightIcon),
),
const SizedBox(height: 15),
const Flexible(
child: FittedBox(
child: BodySmall(
text: 'Backlight',
textAlign: TextAlign.center,
),
),
),
],
),
),
),
const SizedBox(width: 10),
Expanded(
child: DefaultContainer(
onTap: () async {
var value = await showDialog(
context: context,
builder: (context) {
return SelectSwitchDialog(
switch1Title: model.scene_1,
switch2Title: model.scene_2,
switch3Title: model.scene_3,
switch4Title: model.scene_4,
switch5Title: model.scene_5,
switch6Title: model.scene_6,
cancelTab: () {
Navigator.of(context).pop();
},
confirmTab: (v) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
SixSelectSceneFourPage(
deviceId: device!.uuid,
switchSelected: v,
),
),
);
},
);
},
);
if (value == true) {
Future.delayed(
const Duration(
milliseconds: 200), () {
_bloc.add(
const SexSceneSwitchInitial());
});
}
},
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46,
maxWidth: 50,
),
child: SvgPicture.asset(
Assets.addSceneIcon),
),
const SizedBox(height: 15),
const Flexible(
child: FittedBox(
child: BodySmall(
text: 'Add Scene',
textAlign: TextAlign.center,
),
),
),
],
),
),
),
],
),
),
],
),
),
],
),
),
);
},
),
);
}
}

View File

@ -1,193 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SixSwitchsCardDialog extends StatelessWidget {
final String? switch1Title;
final String? switch2Title;
final String? switch3Title;
final String? switch4Title;
final String? switch5Title;
final String? switch6Title;
final String switch1Up;
final String switch1Down;
final String switch2Up;
final String switch2Down;
final String switch3Down;
final String switch3Up;
final VoidCallback onSwitch1UpTap;
final VoidCallback onSwitch1DownTap;
final VoidCallback onSwitch2UpTap;
final VoidCallback onSwitch2DownTap;
final VoidCallback onSwitch3DownTap;
final VoidCallback onSwitch3UpTap;
SixSwitchsCardDialog(
{required this.switch1Down,
required this.switch1Up,
required this.switch2Down,
required this.switch2Up,
required this.onSwitch1UpTap,
required this.onSwitch1DownTap,
required this.onSwitch2UpTap,
required this.onSwitch2DownTap,
required this.onSwitch3DownTap,
required this.onSwitch3UpTap,
required this.switch3Down,
this.switch1Title,
this.switch2Title,
this.switch3Title,
this.switch4Title,
this.switch5Title,
this.switch6Title,
required this.switch3Up});
@override
Widget build(BuildContext context) {
return Expanded(
flex: 4,
child: InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: ColorsManager.onPrimaryColor,
boxShadow: [
BoxShadow(
color: Colors.white.withOpacity(0.1),
blurRadius: 24,
offset: const Offset(-2, -2),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.black.withOpacity(0.11),
blurRadius: 5,
offset: const Offset(2, 0),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.white.withOpacity(0.13),
blurRadius: 10,
offset: const Offset(5, 1),
blurStyle: BlurStyle.inner,
),
],
),
child: SizedBox(
height: 300,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
// Switch 1
_buildSwitchColumn(
switchUp: switch1Up,
switchDown: switch1Down,
onUpTap: onSwitch1UpTap,
onDownTap: onSwitch1DownTap,
titleDown: switch4Title!,
titleUp: switch1Title!),
_buildDivider(),
// Switch 2
_buildSwitchColumn(
switchUp: switch2Up,
switchDown: switch2Down,
onDownTap: onSwitch2UpTap,
onUpTap: onSwitch2DownTap,
titleDown: switch5Title!,
titleUp: switch2Title!),
_buildDivider(),
// Switch 3
_buildSwitchColumn(
switchUp: switch3Up,
switchDown: switch3Down,
onDownTap: onSwitch3UpTap,
onUpTap: onSwitch3DownTap,
titleDown: switch6Title!,
titleUp: switch3Title!),
],
),
),
),
),
),
],
),
),
);
}
Widget _buildSwitchColumn({
String switchUp = '',
String titleUp = '',
String titleDown = '',
String switchDown = '',
VoidCallback? onUpTap,
VoidCallback? onDownTap,
}) {
return Expanded(
child: Padding(
padding: const EdgeInsets.only(top: 30, bottom: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
InkWell(
onTap: onUpTap,
child: Container(
height: 20,
width: 20,
child: SvgPicture.asset(switchUp),
),
),
BodySmall(
text: titleUp,
)
],
),
Column(
children: [
InkWell(
onTap: onDownTap,
child: Container(
height: 20,
width: 20,
child: SvgPicture.asset(switchDown),
),
),
BodySmall(
text: titleDown,
)
],
),
],
),
),
);
}
Widget _buildDivider() {
return Container(
width: 3,
color: ColorsManager.dividerColor,
);
}
}

View File

@ -1,234 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart';
import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_switches_card.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
class FourSceneScreen extends StatelessWidget {
final DeviceModel? device;
const FourSceneScreen({super.key, this.device});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '')
..add(const FourSceneInitial())
..add(const FourSceneInitialInfo())
..add(const FourSceneSwitchInitial()),
child: BlocBuilder<FourSceneBloc, FourSceneState>(
builder: (context, state) {
final _bloc = BlocProvider.of<FourSceneBloc>(context);
FourSceneModelState model = FourSceneModelState(
scene_1: '',
scene_2: '',
scene_3: '',
scene_4: '',
scene_id_group_id: '',
switch_backlight: '',
);
if (state is LoadingNewSate) {
model = state.device;
} else if (state is UpdateState) {
model = state.device;
}
return DefaultScaffold(
title: _bloc.deviceInfo.name,
actions: [
InkWell(
onTap: () async {
var val = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SettingsPage(device: device!),
),
);
if (val == null) {
_bloc.add(const FourSceneInitial());
_bloc.add(const FourSceneInitialInfo());
_bloc.add(const FourSceneSwitchInitial());
}
},
child: SvgPicture.asset(Assets.assetsIconsSettings),
),
const SizedBox(width: 10),
],
child: state is FourSceneLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
)
: RefreshIndicator(
onRefresh: () async {
_bloc.add(const FourSceneInitial());
},
child: ListView(
children: [
SizedBox(
height: MediaQuery.sizeOf(context).height * 0.8,
child: Column(
children: [
FourSwitchsCard(
title1: model.scene_1,
title2: model.scene_2,
title3: model.scene_3,
title4: model.scene_4,
switch1: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch2: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch3: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
switch4: _bloc.deviceStatus.switch_backlight
? Assets.switchOn
: Assets.switchOff,
onSwitch1UpTap: () {
debugPrint("Switch 1 Up tapped");
},
onSwitch2UpTap: () {
debugPrint("Switch 2 Up tapped");
},
onSwitch3DownTap: () {
debugPrint("onSwitch3DownTap");
},
onSwitch4DownTap: () {
debugPrint("onSwitch4DownTap");
},
),
Flexible(
child: Row(
children: [
Expanded(
child: DefaultContainer(
onTap: () {
_bloc.add(ChangeSwitchStatusEvent());
},
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46,
maxWidth: 50,
),
child: SvgPicture.asset(
Assets.backlightIcon),
),
const SizedBox(height: 15),
const Flexible(
child: FittedBox(
child: BodySmall(
text: 'Backlight',
textAlign: TextAlign.center,
),
),
),
],
),
),
),
const SizedBox(width: 10),
Expanded(
child: DefaultContainer(
onTap: () async {
var value = await showDialog(
context: context,
builder: (context) {
return FourSelectSwitchDialog(
switch1Title: model.scene_1,
switch2Title: model.scene_2,
switch3Title: model.scene_3,
switch4Title: model.scene_4,
cancelTab: () {
Navigator.of(context).pop();
},
confirmTab:
(switchSelected) async {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
FourSelectSceneFourPage(
switchSelected:
switchSelected,
deviceId: device!.uuid,
),
),
);
},
);
},
);
if (value == true) {
Future.delayed(
const Duration(
milliseconds: 250), () {
_bloc.add(
const FourSceneSwitchInitial());
});
}
},
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46,
maxWidth: 50,
),
child: SvgPicture.asset(
Assets.addSceneIcon),
),
const SizedBox(height: 15),
const Flexible(
child: FittedBox(
child: BodySmall(
text: 'Add Scene',
textAlign: TextAlign.center,
),
),
),
],
),
),
),
],
),
),
],
),
),
],
),
),
);
},
),
);
}
}

View File

@ -1,332 +0,0 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart';
import 'package:syncrow_app/features/devices/view/widgets/restart_status_dialog.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class FourSelectSceneFourPage extends StatelessWidget {
final String? switchSelected;
final String? deviceId;
FourSelectSceneFourPage({super.key, this.switchSelected, this.deviceId});
final TextEditingController _searchController = TextEditingController();
final int? selectedSwitchIndex = 0;
final spaces = HomeCubit.getInstance().spaces;
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => FourSceneBloc(fourSceneId: deviceId!)
..add(LoadScenes(
unit: spaces!.first,
unitId: spaces!.first.id,
showInDevice: false,
))
..add(GetSceneBySwitchName(switchName: switchSelected)),
child: BlocBuilder<FourSceneBloc, FourSceneState>(
builder: (context, state) {
final sensorBloc = BlocProvider.of<FourSceneBloc>(context);
if (state is SaveSelectionSuccessState) {
Future.delayed(const Duration(milliseconds: 250), () {
Navigator.of(context).pop(true);
Navigator.of(context).pop(true);
});
}
return DefaultScaffold(
title: 'Select Scene',
actions: [_buildSaveButton(context, state, sensorBloc)],
child: _buildSceneContent(context, sensorBloc, state),
);
},
),
);
}
// Save button builder
Widget _buildSaveButton(
BuildContext context, FourSceneState state, FourSceneBloc sensorBloc) {
final bool canSave = state is SceneSelectionUpdatedState;
return GestureDetector(
onTap: canSave
? () {
context.read<FourSceneBloc>().add(AssignDeviceScene(
sceneUuid: sensorBloc.selectedSceneId,
switchName: switchSelected,
unit: spaces!.first));
}
: null,
child: Padding(
padding: const EdgeInsets.only(left: 10, right: 15),
child: BodyMedium(
text: 'Save',
fontWeight: FontWeight.w700,
fontSize: 16,
fontColor: canSave
? ColorsManager.slidingBlueColor
: ColorsManager.primaryTextColor,
),
),
);
}
// Loading indicator
Widget _buildLoadingIndicator() {
return const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
);
}
// Main scene content with search bar and grid
Widget _buildSceneContent(
BuildContext context, FourSceneBloc sensorBloc, FourSceneState state) {
return Column(
children: [
_buildSearchBar(sensorBloc),
const SizedBox(height: 20),
Expanded(
child: state is FourSceneLoadingState
? _buildLoadingIndicator()
: sensorBloc.filteredScenes.isEmpty
? const Center(
child: SizedBox(
child: BodySmall(text: 'No Scenes available'),
),
)
: _buildSceneGrid(sensorBloc, state),
),
],
);
}
// Search bar widget
Widget _buildSearchBar(FourSceneBloc sensorBloc) {
return TextFormField(
controller: _searchController,
onChanged: (value) {
sensorBloc.add(SearchScenesEvent(query: value));
},
decoration: InputDecoration(
hintText: 'Search',
hintStyle: const TextStyle(
color: ColorsManager.textGray,
fontSize: 16,
fontWeight: FontWeight.w400),
suffixIcon: Container(
padding: const EdgeInsets.all(5.0),
margin: const EdgeInsets.all(10.0),
child: SvgPicture.asset(
Assets.searchIcon,
fit: BoxFit.contain,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
);
}
// Scene grid builder
Widget _buildSceneGrid(FourSceneBloc sensorBloc, FourSceneState state) {
final scenes = sensorBloc.filteredScenes;
return GridView.builder(
itemCount: scenes.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
mainAxisExtent: 120,
),
itemBuilder: (context, index) {
final scene = scenes[index];
// Check if this scene is currently selected
bool isSelected = scene.id ==
(state is SceneSelectionUpdatedState
? state.selectedSceneId
: sensorBloc.selectedFormApiSceneId);
return SceneItem(
id: scene.id,
value: isSelected, // Pass isSelected to the SceneItem
disablePlayButton: false,
onChanged: (newSelection) {
// If selected, assign the scene
sensorBloc.add(SelectOptionEvent(selectedOption: scene.id));
sensorBloc.add(SelectSceneEvent(
selectedSceneId: scene.id, isSelected: newSelection));
},
icon: scene.iconInBytes,
title: scene.name,
);
},
);
}
}
class SceneItem extends StatelessWidget {
final String id;
final Uint8List icon;
final String title;
final bool disablePlayButton;
final bool value;
final Function(bool) onChanged;
const SceneItem({
required this.id,
required this.icon,
required this.title,
this.disablePlayButton = false,
required this.value,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 2,
spreadRadius: 1,
offset: Offset(0, 3),
),
],
),
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (!disablePlayButton)
Image.memory(
icon,
height: 32,
width: 32,
fit: BoxFit.fill,
errorBuilder: (context, error, stackTrace) => Image.asset(
Assets.assetsIconsLogo,
height: 32,
width: 32,
fit: BoxFit.fill),
),
],
),
CircularCheckbox(
value: value,
onChanged: (isSelected) => onChanged(isSelected!),
),
],
),
BodyMedium(
text: title,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w700,
color: ColorsManager.secondaryTextColor),
textAlign: TextAlign.center,
),
],
),
);
}
}
// Widget for the static "Create Scene" button
class CreateSceneItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 5,
spreadRadius: 2,
offset: Offset(0, 3),
),
],
),
padding: const EdgeInsets.all(16),
child: const Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.add_circle,
color: ColorsManager.grayButtonColors, size: 36),
BodyMedium(
text: 'Create Scene',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: ColorsManager.secondaryTextColor),
textAlign: TextAlign.center,
),
],
),
);
}
}
// if (index == scenes.length) {
// return InkWell(
// onTap: () => Navigator.pushNamed(
// NavigationService.navigatorKey.currentContext!,
// Routes.sceneTasksRoute,
// arguments: SceneSettingsRouteArguments(
// sceneType: '',
// sceneId: '',
// sceneName: '',
// ),
// ),
// child: CreateSceneItem(),
// );
// } else {
// final scene = scenes[index];
// bool isSelected = scene.id ==
// (state is SceneSelectionUpdatedState
// ? state.selectedSceneId
// : sensorBloc.selectedFormApiSceneId);
// return SceneItem(
// id: scene.id,
// value: isSelected,
// disablePlayButton: false,
// onChanged: (isSelected) {
// sensorBloc.add(SelectOptionEvent(selectedOption: scene.id));
// sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id));
// },
// icon: scene.iconInBytes,
// title: scene.name,
// );
// }

View File

@ -1,160 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_switches_card_dialog.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class FourSelectSwitchDialog extends StatefulWidget {
final Function()? cancelTab;
final Function(String)? confirmTab;
final String switch1Title;
final String switch2Title;
final String switch3Title;
final String switch4Title;
const FourSelectSwitchDialog(
{super.key,
required this.cancelTab,
required this.confirmTab,
required this.switch1Title,
required this.switch2Title,
required this.switch3Title,
required this.switch4Title});
@override
State<FourSelectSwitchDialog> createState() => _FourSelectSwitchDialogState();
}
class _FourSelectSwitchDialogState extends State<FourSelectSwitchDialog> {
String selectedSwitchName = ''; // State variable to track selected switch
@override
Widget build(BuildContext context) {
return AlertDialog(
backgroundColor: ColorsManager.onPrimaryColor,
contentPadding: EdgeInsets.zero,
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const SizedBox(height: 10),
const BodyLarge(
text: 'Select Switch',
fontWeight: FontWeight.w700,
fontColor: ColorsManager.primaryColor,
fontSize: 16,
),
const Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Divider(color: ColorsManager.textGray),
),
const SizedBox(height: 20),
Row(
children: [
FourSwitchsCardDialog(
switch1Title: widget.switch1Title,
switch2Title: widget.switch2Title,
switch3Title: widget.switch3Title,
switch4Title: widget.switch4Title,
switch1Down: selectedSwitchName == 'scene_3'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch1Up: selectedSwitchName == 'scene_1'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch2Down: selectedSwitchName == 'scene_4'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
switch2Up: selectedSwitchName == 'scene_2'
? Assets.removeSceneIcon
: Assets.addSwitchIcon,
onSwitch1UpTap: () {
setState(() => selectedSwitchName = 'scene_1');
},
onSwitch1DownTap: () {
setState(() => selectedSwitchName = 'scene_3');
},
onSwitch2UpTap: () {
setState(() => selectedSwitchName = 'scene_4');
},
onSwitch2DownTap: () {
setState(() => selectedSwitchName = 'scene_2');
},
),
],
),
const SizedBox(height: 20),
const Padding(
padding: EdgeInsets.only(bottom: 15, left: 5, right: 5, top: 10),
child: Center(
child: Text(
'Please select one of the switches available to continue',
textAlign: TextAlign.center,
),
),
),
Row(
children: [
Expanded(
child: Container(
decoration: const BoxDecoration(
border: Border(
right:
BorderSide(color: ColorsManager.textGray, width: 0.5),
top: BorderSide(color: ColorsManager.textGray, width: 1.0),
)),
child: SizedBox(
child: InkWell(
onTap: widget.cancelTab,
child: const Padding(
padding: EdgeInsets.all(15),
child: Center(
child: Text(
'Cancel',
style: TextStyle(
color: ColorsManager.textPrimaryColor,
fontSize: 14,
fontWeight: FontWeight.w400),
),
),
),
),
),
),
),
Expanded(
child: Container(
decoration: const BoxDecoration(
border: Border(
left: BorderSide(color: ColorsManager.textGray, width: 0.5),
top: BorderSide(color: ColorsManager.textGray, width: 1.0),
)),
child: InkWell(
onTap: selectedSwitchName == ''
? () {}
: () => widget.confirmTab!(selectedSwitchName),
child: Padding(
padding: EdgeInsets.all(15),
child: Center(
child: Text(
'Next',
style: TextStyle(
color: selectedSwitchName == ''
? ColorsManager.textPrimaryColor
.withOpacity(0.6)
: ColorsManager.primaryColor,
fontSize: 14,
fontWeight: FontWeight.w400),
),
),
),
),
),
),
],
)
],
),
);
}
}

View File

@ -1,165 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class FourSwitchsCard extends StatelessWidget {
final String switch1;
final String title1;
final String switch3;
final String title3;
final String switch2;
final String title2;
final String switch4;
final String title4;
final VoidCallback onSwitch1UpTap;
final VoidCallback onSwitch4DownTap;
final VoidCallback onSwitch2UpTap;
final VoidCallback onSwitch3DownTap;
FourSwitchsCard({
required this.title1,
required this.title2,
required this.title3,
required this.title4,
required this.switch3,
required this.switch1,
required this.switch4,
required this.switch2,
required this.onSwitch1UpTap,
required this.onSwitch3DownTap,
required this.onSwitch2UpTap,
required this.onSwitch4DownTap,
});
@override
Widget build(BuildContext context) {
return Expanded(
flex: 4,
child: InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: ColorsManager.onPrimaryColor,
boxShadow: [
BoxShadow(
color: Colors.white.withOpacity(0.1),
blurRadius: 24,
offset: const Offset(-2, -2),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.black.withOpacity(0.11),
blurRadius: 5,
offset: const Offset(2, 0),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.white.withOpacity(0.13),
blurRadius: 10,
offset: const Offset(5, 1),
blurStyle: BlurStyle.inner,
),
],
),
child: SizedBox(
height: 300,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildSwitchColumn(
switchUp: switch1,
switchDown: switch3,
onUpTap: onSwitch1UpTap,
onDownTap: onSwitch3DownTap,
titleDown: title3,
titleUp: title1),
_buildDivider(),
_buildSwitchColumn(
titleDown: title4,
titleUp: title2,
switchUp: switch2,
switchDown: switch4,
onUpTap: onSwitch2UpTap,
onDownTap: onSwitch4DownTap),
],
),
),
),
),
),
],
),
),
);
}
Widget _buildSwitchColumn({
String switchUp = '',
String switchDown = '',
String titleUp = '',
String titleDown = '',
VoidCallback? onUpTap,
VoidCallback? onDownTap,
}) {
return Expanded(
child: Padding(
padding: const EdgeInsets.only(top: 30, bottom: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
InkWell(
onTap: onUpTap,
child: Container(
height: 20,
width: 20,
child: SvgPicture.asset(switchUp),
),
),
Text(titleUp)
],
),
Column(
children: [
InkWell(
onTap: onDownTap,
child: Container(
height: 20,
width: 20,
child: SvgPicture.asset(switchDown),
),
),
Text(titleDown)
],
),
],
),
),
);
}
Widget _buildDivider() {
return Container(
width: 3,
color: ColorsManager.dividerColor,
);
}
}

View File

@ -1,171 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class FourSwitchsCardDialog extends StatelessWidget {
final String? switch1Title;
final String? switch2Title;
final String? switch3Title;
final String? switch4Title;
final String switch1Up;
final String switch1Down;
final String switch2Up;
final String switch2Down;
final VoidCallback onSwitch1UpTap;
final VoidCallback onSwitch1DownTap;
final VoidCallback onSwitch2UpTap;
final VoidCallback onSwitch2DownTap;
FourSwitchsCardDialog({
required this.switch1Down,
required this.switch1Up,
required this.switch2Down,
required this.switch2Up,
required this.onSwitch1UpTap,
required this.onSwitch1DownTap,
required this.onSwitch2UpTap,
required this.onSwitch2DownTap,
this.switch1Title,
this.switch2Title,
this.switch3Title,
this.switch4Title,
});
@override
Widget build(BuildContext context) {
return Expanded(
flex: 4,
child: InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: ColorsManager.onPrimaryColor,
boxShadow: [
BoxShadow(
color: Colors.white.withOpacity(0.1),
blurRadius: 24,
offset: const Offset(-2, -2),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.black.withOpacity(0.11),
blurRadius: 5,
offset: const Offset(2, 0),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color: Colors.white.withOpacity(0.13),
blurRadius: 10,
offset: const Offset(5, 1),
blurStyle: BlurStyle.inner,
),
],
),
child: SizedBox(
height: 300,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
// Switch 1
_buildSwitchColumn(
switchUp: switch1Up,
switchDown: switch1Down,
onUpTap: onSwitch1UpTap,
onDownTap: onSwitch1DownTap,
titleDown: switch3Title!,
titleUp: switch1Title!),
_buildDivider(),
// Switch 2
_buildSwitchColumn(
switchUp: switch2Up,
switchDown: switch2Down,
onDownTap: onSwitch2UpTap,
onUpTap: onSwitch2DownTap,
titleDown: switch4Title!,
titleUp: switch2Title!),
],
),
),
),
),
),
],
),
),
);
}
Widget _buildSwitchColumn({
String switchUp = '',
String titleUp = '',
String titleDown = '',
String switchDown = '',
VoidCallback? onUpTap,
VoidCallback? onDownTap,
}) {
return Expanded(
child: Padding(
padding: const EdgeInsets.only(top: 30, bottom: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
InkWell(
onTap: onUpTap,
child: Container(
height: 20,
width: 20,
child: SvgPicture.asset(switchUp),
),
),
BodySmall(
text: titleUp,
)
],
),
Column(
children: [
InkWell(
onTap: onDownTap,
child: Container(
height: 20,
width: 20,
child: SvgPicture.asset(switchDown),
),
),
BodySmall(
text: titleDown,
)
],
),
],
),
),
);
}
Widget _buildDivider() {
return Container(
width: 3,
color: ColorsManager.dividerColor,
);
}
}

View File

@ -36,7 +36,7 @@ class _RoomPageState extends State<RoomPage> {
final query = _searchController.text.toLowerCase();
setState(() {
_filteredDevices = widget.room.devices!
.where((device) => device.name!.toLowerCase().contains(query))
.where((device) => device.type!.toLowerCase().contains(query))
.toList();
});
}
@ -51,9 +51,7 @@ class _RoomPageState extends State<RoomPage> {
decoration: InputDecoration(
hintText: 'Search',
hintStyle: const TextStyle(
color: ColorsManager.textGray,
fontSize: 16,
fontWeight: FontWeight.w400),
color: ColorsManager.textGray, fontSize: 16, fontWeight: FontWeight.w400),
prefixIcon: Container(
padding: const EdgeInsets.all(5.0),
margin: const EdgeInsets.all(10.0),

View File

@ -7,11 +7,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/door_sensor/door_sensor_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_door_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart';
@ -68,7 +66,7 @@ class RoomPageSwitch extends StatelessWidget {
Flexible(
child: FittedBox(
child: Text(
device.name ?? "",
device.type ?? "",
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: context.bodyLarge.copyWith(
@ -214,28 +212,12 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
WaterLeakScreen(device: device)));
case DeviceType.SixScene:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
SixSceneScreen(device: device)));
case DeviceType.FourScene:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
FourSceneScreen(device: device)));
case DeviceType.SOS:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
SosScreen(device: device)));
break;
default:
}

View File

@ -11,8 +11,7 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class AlarmManagementPage extends StatelessWidget {
final String sosId;
const AlarmManagementPage({super.key, required this.sosId});
const AlarmManagementPage({super.key});
@override
Widget build(BuildContext context) {

View File

@ -5,6 +5,7 @@ import 'package:intl/intl.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
@ -46,6 +47,7 @@ class _SosRecordsScreenState extends State<SosRecordsScreen> {
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
final String formattedDate =
DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
if (groupedRecords.containsKey(formattedDate)) {
groupedRecords[formattedDate]!.add(record);
} else {
@ -179,8 +181,10 @@ class _SosRecordsScreenState extends State<SosRecordsScreen> {
height: 25,
width: 25,
),
title: const Text(
"SOS Alert Triggered",
title: Text(
record.value == 'true'
? "Leak Detected"
: "Normal",
style: const TextStyle(
fontWeight:
FontWeight.bold,
@ -188,7 +192,7 @@ class _SosRecordsScreenState extends State<SosRecordsScreen> {
),
),
subtitle:
Text(formattedTime),
Text('$formattedTime'),
),
if (idx !=
recordsForDate.length - 1)

View File

@ -6,9 +6,9 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_alarm_management_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_records_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_settings.dart';
import 'package:syncrow_app/features/shared_widgets/battery_bar.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
@ -22,48 +22,40 @@ class SosScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => SosBloc(sosId: device?.uuid ?? '')
..add(const SosInitial())
..add(SosInitialDeviseInfo()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model = SosModel(
batteryPercentage: 0,
sosContactState: '',
);
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return DefaultScaffold(
title: sensor.deviceInfo.name,
actions: [
InkWell(
onTap: () async {
var val = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SettingsPage(device: device!),
),
);
if (val == null) {
sensor.add(SosInitialDeviseInfo());
sensor.add(const SosInitial());
}
},
child: SvgPicture.asset(Assets.assetsIconsSettings),
),
const SizedBox(width: 10),
],
child: state is SosLoadingState
return DefaultScaffold(
title: 'SOS',
actions: [
InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SosSettings(device: device!)),
);
},
child: SvgPicture.asset(Assets.assetsIconsSettings)),
const SizedBox(
width: 10,
)
],
child: BlocProvider(
create: (context) =>
SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model =
SosModel(batteryPercentage: 0, sosContactState: 'normal');
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
@ -76,17 +68,15 @@ class SosScreen extends StatelessWidget {
child: Column(
children: [
BatteryBar(
batteryPercentage:
sensor.deviceStatus.batteryPercentage,
batteryPercentage: model.batteryPercentage,
),
Expanded(
flex: 4,
child: InkWell(
overlayColor: MaterialStateProperty.all(
overlayColor: WidgetStateProperty.all(
Colors.transparent),
onTap: () {
// Add functionality for the main SOS button here
},
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
@ -121,8 +111,7 @@ class SosScreen extends StatelessWidget {
],
),
child: SvgPicture.asset(
sensor.deviceStatus.sosContactState !=
'sos'
model.sosContactState == 'normal'
? Assets.redSos
: Assets.greenSos,
fit: BoxFit.fill,
@ -140,10 +129,9 @@ class SosScreen extends StatelessWidget {
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
SosRecordsScreen(
sosId: device!.uuid!),
),
builder: (context) =>
SosRecordsScreen(
sosId: device!.uuid!)),
);
},
child: Column(
@ -154,13 +142,13 @@ class SosScreen extends StatelessWidget {
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46,
maxWidth: 50,
),
maxHeight: 46, maxWidth: 50),
child: SvgPicture.asset(
Assets.doorRecordsIcon),
),
const SizedBox(height: 15),
const SizedBox(
height: 15,
),
const Flexible(
child: FittedBox(
child: BodySmall(
@ -173,17 +161,16 @@ class SosScreen extends StatelessWidget {
),
),
),
const SizedBox(width: 10),
const SizedBox(
width: 10,
),
Expanded(
child: DefaultContainer(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
AlarmManagementPage(
sosId: device!.uuid!,
),
),
builder: (context) =>
const AlarmManagementPage()),
);
},
child: Column(
@ -194,13 +181,13 @@ class SosScreen extends StatelessWidget {
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46,
maxWidth: 50,
),
maxHeight: 46, maxWidth: 50),
child: SvgPicture.asset(Assets
.doorNotificationSetting),
),
const SizedBox(height: 15),
const SizedBox(
height: 15,
),
const Flexible(
child: FittedBox(
child: BodySmall(
@ -215,15 +202,15 @@ class SosScreen extends StatelessWidget {
),
],
),
),
)
],
),
),
],
),
),
);
},
);
},
),
),
);
}

View File

@ -0,0 +1,151 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/question_page.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class FaqSosPage extends StatelessWidget {
final DeviceModel? device;
const FaqSosPage({super.key, this.device});
@override
Widget build(BuildContext context) {
TextEditingController _searchController = TextEditingController();
return DefaultScaffold(
title: 'FAQ',
child: BlocProvider(
create: (context) =>
SosBloc(sosId: device?.uuid ?? '')..add(const SosInitialQuestion()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<SosBloc>(context);
List<QuestionModel> displayedQuestions = [];
if (state is FaqSearchState) {
displayedQuestions = state.filteredFaqQuestions;
} else if (state is FaqLoadedState) {
displayedQuestions = state.filteredFaqQuestions;
}
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
sensor.add(const SosInitial());
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
DefaultContainer(
padding: const EdgeInsets.all(5),
child: TextFormField(
controller: _searchController,
onChanged: (value) {
sensor.add(SearchFaqEvent(value));
},
decoration: InputDecoration(
hintText: 'Enter your questions',
hintStyle: const TextStyle(
color: ColorsManager.textGray,
fontSize: 16,
fontWeight: FontWeight.w400),
suffixIcon: Container(
padding: const EdgeInsets.all(5.0),
margin: const EdgeInsets.all(10.0),
child: SvgPicture.asset(
Assets.searchIcon,
fit: BoxFit.contain,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.04,
),
BodyMedium(
text: _searchController.text.isEmpty
? 'Device Related FAQs'
: '${displayedQuestions.length} Help Topics',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
Expanded(
child: DefaultContainer(
child: ListView.builder(
shrinkWrap: true,
itemCount: displayedQuestions.length,
itemBuilder: (context, index) {
final faq = displayedQuestions[index];
return InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => QuestionPage(
questionModel: faq,
)),
);
},
child: SizedBox(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: BodyMedium(
fontSize: 14,
fontWeight: FontWeight.w400,
text: faq.question,
),
),
const Icon(
Icons.keyboard_arrow_right,
color: ColorsManager.textGray,
),
],
),
),
const Divider(
color: ColorsManager.dividerColor,
),
],
),
),
);
},
)),
),
],
),
);
},
),
),
);
}
}

View File

@ -0,0 +1,195 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class LocationSosPage extends StatelessWidget {
final SpaceModel? space;
LocationSosPage({super.key, this.space});
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider(
create: (context) =>
SosBloc(sosId: '')..add(FetchRoomsEvent(unit: space!)),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model =
SosModel(batteryPercentage: 0, sosContactState: 'normal');
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator(),
),
)
: DefaultScaffold(
actions: [
BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final bool canSave = state is OptionSelectedState &&
state.hasSelectionChanged;
return InkWell(
onTap: canSave
? () {
context
.read<SosBloc>()
.add(SaveSelectionEvent());
}
: null,
child: BodyMedium(
text: 'Save',
fontWeight: FontWeight.w700,
fontSize: 16,
fontColor: canSave
? ColorsManager.slidingBlueColor
: ColorsManager.primaryTextColor,
),
);
},
),
const SizedBox(width: 20),
],
child: RefreshIndicator(
onRefresh: () async {
sensor.add(const SosInitial());
},
child: ListView(
shrinkWrap: true,
padding: const EdgeInsets.symmetric(vertical: 20),
children: [
const BodyMedium(
text: 'Smart Device Location',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
const SizedBox(height: 5),
DefaultContainer(
padding: const EdgeInsets.all(20),
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: sensor.roomsList.length,
itemBuilder: (context, index) {
final room = sensor.roomsList![index];
return Column(
children: [
_buildCheckboxOption(
label: room.name!,
isSelected:
state is OptionSelectedState &&
state.selectedOption == room.name,
onTap: (v) {
context.read<SosBloc>().add(
SelectOptionEvent(
selectedOption: v));
},
),
if (index <
sensor.roomsList.length - 1) ...[
const SizedBox(height: 10),
const Divider(
color: ColorsManager.dividerColor,
),
const SizedBox(height: 10),
],
],
);
},
),
),
],
),
),
);
},
),
),
);
}
Widget _buildCheckboxOption({
required String label,
required bool isSelected,
required Function(String) onTap,
}) {
return Padding(
padding: const EdgeInsets.only(bottom: 10, top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BodyMedium(
text: label,
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w400),
),
CircularCheckbox(
value: isSelected,
onChanged: (bool? value) {
if (value == true) {
onTap(label);
}
},
),
],
),
);
}
}
class CircularCheckbox extends StatefulWidget {
final bool value;
final ValueChanged<bool?> onChanged;
CircularCheckbox({required this.value, required this.onChanged});
@override
_CircularCheckboxState createState() => _CircularCheckboxState();
}
class _CircularCheckboxState extends State<CircularCheckbox> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
widget.onChanged(!widget.value);
},
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: widget.value
? ColorsManager.primaryColorWithOpacity.withOpacity(0.01)
: Colors.grey,
width: 2.0,
),
color: widget.value
? ColorsManager.primaryColorWithOpacity
: Colors.transparent,
),
width: 24.0,
height: 24.0,
child: widget.value
? const Icon(
Icons.check,
color: Colors.white,
size: 16.0,
)
: null,
),
);
}
}

View File

@ -0,0 +1,143 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/question_model.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class QuestionPage extends StatelessWidget {
final QuestionModel? questionModel;
const QuestionPage({super.key, this.questionModel});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'FAQ',
child: BlocProvider(
create: (context) => SosBloc(sosId: '')..add(const SosInitial()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model =
SosModel(batteryPercentage: 0, sosContactState: 'normal');
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
sensor.add(const SosInitial());
},
child: Column(
children: [
DefaultContainer(
padding: EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BodyLarge(
text: questionModel!.question,
fontSize: 22,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
SizedBox(
height: 15,
),
BodyMedium(
text: questionModel!.answer,
fontSize: 14,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.secondaryTextColor,
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.15,
),
Center(
child: SizedBox(
width: 180,
child: DefaultButton(
backgroundColor: ColorsManager.grayButtonColors,
borderRadius: 50,
onPressed: () {},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.thumbUp,
fit: BoxFit.fill,
),
SizedBox(
width: 10,
),
BodyMedium(
text: 'Helpful',
fontSize: 12,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
],
)),
),
),
SizedBox(
height: 15,
),
Center(
child: SizedBox(
width: 180,
child: DefaultButton(
backgroundColor: ColorsManager.grayButtonColors,
borderRadius: 50,
onPressed: () {},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.thumbDown,
fit: BoxFit.fill,
),
SizedBox(
width: 10,
),
BodyMedium(
text: 'Not Helpful',
fontSize: 12,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
],
)),
),
),
],
));
},
),
),
);
}
}

View File

@ -1,34 +1,40 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class ShareDevicePage extends StatelessWidget {
class ShareSosPage extends StatelessWidget {
final DeviceModel? device;
const ShareDevicePage({super.key, this.device});
const ShareSosPage({super.key, this.device});
@override
Widget build(BuildContext context) {
var spaces = HomeCubit.getInstance().spaces;
return DefaultScaffold(
title: 'Share Device',
child: BlocProvider(
create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '')
..add(const FourSceneInitial()),
child: BlocBuilder<FourSceneBloc, FourSceneState>(
create: (context) =>
SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<FourSceneBloc>(context);
return state is LoadingNewSate
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model =
SosModel(batteryPercentage: 0, sosContactState: 'normal');
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
@ -37,14 +43,11 @@ class ShareDevicePage extends StatelessWidget {
)
: RefreshIndicator(
onRefresh: () async {
sensor.add(const FourSceneInitial());
sensor.add(const SosInitial());
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.05,
),
const BodyLarge(
text: 'Sharing Method Not Supported',
fontSize: 15,
@ -83,13 +86,8 @@ class ShareDevicePage extends StatelessWidget {
child: DefaultButton(
backgroundColor: ColorsManager.blueColor1,
borderRadius: 50,
onPressed: () {
Navigator.of(context).push(CustomPageRoute(
builder: (context) => HomeSettingsView(
space: spaces!.first,
)));
},
child: const Text('Add Home Member')),
onPressed: () {},
child: Text('Add Home Member')),
),
)
],

View File

@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
@ -12,23 +12,29 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SettingInfoPage extends StatelessWidget {
class SosInfoPge extends StatelessWidget {
final DeviceModel? device;
const SettingInfoPage({super.key, this.device});
const SosInfoPge({super.key, this.device});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Device Information',
child: BlocProvider(
create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '')
..add(const DeviceSettingInitial())
..add(const DeviceSettingInitialInfo()),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
create: (context) =>
SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
return state is DeviceSettingLoadingState
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model =
SosModel(batteryPercentage: 0, sosContactState: 'normal');
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
@ -37,11 +43,11 @@ class SettingInfoPage extends StatelessWidget {
)
: RefreshIndicator(
onRefresh: () async {
_bloc.add(const DeviceSettingInitial());
sensor.add(const SosInitial());
},
child: DefaultContainer(
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5),
padding: const EdgeInsets.only(left: 10, right: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@ -56,28 +62,12 @@ class SettingInfoPage extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width:
MediaQuery.of(context).size.width * 0.61,
child: BodySmall(
text: _bloc.deviceInfo.productUuid,
fontColor: ColorsManager.primaryTextColor,
),
const BodySmall(
text: 'bf3575d0e0c8b6e0a6hybl',
fontColor: ColorsManager.primaryTextColor,
),
InkWell(
onTap: () {
Clipboard.setData(
ClipboardData(
text: _bloc.deviceInfo.productUuid,
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Copied to Clipboard"),
),
);
},
onTap: () {},
child: const Row(
children: [
Icon(
@ -96,18 +86,18 @@ class SettingInfoPage extends StatelessWidget {
const Divider(
color: ColorsManager.dividerColor,
),
Column(
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const BodyLarge(
BodyLarge(
text: 'MAC',
fontSize: 15,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
BodySmall(
text: _bloc.deviceInfo.macAddress,
text: 'bf3575d0e0c8b6e0a6hybl',
fontColor: ColorsManager.primaryTextColor,
),
],
@ -115,18 +105,18 @@ class SettingInfoPage extends StatelessWidget {
const Divider(
color: ColorsManager.dividerColor,
),
Column(
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const BodyLarge(
BodyLarge(
text: 'Time Zone',
fontSize: 15,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blackColor,
),
BodySmall(
text: _bloc.deviceInfo.timeZone,
text: 'Asia/Dubai',
fontColor: ColorsManager.primaryTextColor,
),
],

View File

@ -2,21 +2,22 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/location_setting.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/location_setting.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SettingProfilePage extends StatelessWidget {
class SosProfilePage extends StatelessWidget {
final DeviceModel? device;
const SettingProfilePage({super.key, this.device});
const SosProfilePage({super.key, this.device});
@override
Widget build(BuildContext context) {
@ -24,19 +25,20 @@ class SettingProfilePage extends StatelessWidget {
return DefaultScaffold(
title: 'Device Settings',
leading: IconButton(
onPressed: () {
Navigator.of(context).pop(true);
},
icon: const Icon(Icons.arrow_back_ios)),
child: BlocProvider(
create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '')
..add(const DeviceSettingInitial())
..add(const DeviceSettingInitialInfo()),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
create: (context) =>
SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
return state is DeviceSettingLoadingState
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model =
SosModel(batteryPercentage: 0, sosContactState: 'normal');
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
@ -45,47 +47,23 @@ class SettingProfilePage extends StatelessWidget {
)
: RefreshIndicator(
onRefresh: () async {
_bloc.add(const DeviceSettingInitial());
sensor.add(const SosInitial());
},
child: ListView(
children: [
CircleAvatar(
radius: device!.type != "SOS" ? 60 : 52,
radius: 60,
backgroundColor: Colors.white,
child: device!.type == "SOS"
? ClipOval(
child: SvgPicture.asset(
Assets.sosHomeIcon,
fit: BoxFit.fitHeight,
height:
MediaQuery.of(context).size.height * 0.13,
))
: CircleAvatar(
radius: 55,
backgroundColor: ColorsManager.graysColor,
child: ClipOval(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Center(
child: SvgPicture.asset(
device!.type == "4S"
? Assets.fourSceneIcon
: Assets.sixSceneIcon,
fit: BoxFit.contain,
height: MediaQuery.of(context)
.size
.height *
0.08,
),
),
],
),
),
),
child: CircleAvatar(
radius: 55,
backgroundColor: Colors.grey,
child: ClipOval(
child: SvgPicture.asset(
Assets.sosProfileIcon,
fit: BoxFit.fill,
),
),
),
),
const SizedBox(
height: 10,
@ -102,14 +80,14 @@ class SettingProfilePage extends StatelessWidget {
child: TextFormField(
maxLength: 30,
style: const TextStyle(
color: Colors.black,
color: ColorsManager.textPrimaryColor,
),
textAlign: TextAlign.center,
focusNode: _bloc.focusNode,
controller: _bloc.nameController,
enabled: _bloc.editName,
focusNode: sensor.focusNode,
controller: sensor.nameController,
enabled: sensor.editName,
onEditingComplete: () {
_bloc.add(const SaveNameEvent());
// sensor.add(SaveNameEvent(context: context));
},
decoration: const InputDecoration(
hintText: "Your Name",
@ -121,18 +99,21 @@ class SettingProfilePage extends StatelessWidget {
),
),
const SizedBox(width: 5),
//editNameSosIcon
InkWell(
onTap: () {
_bloc.add(const ChangeNameEvent(value: true));
sensor
.add(const ChangeNameEvent(value: true));
},
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
padding:
const EdgeInsets.symmetric(horizontal: 5),
child: SvgPicture.asset(
Assets.sosEditProfile,
color: Colors.grey,
height: 18,
width: 18,
Assets.editNameSosIcon,
fit: BoxFit.contain,
height: MediaQuery.of(context).size.height *
0.02,
color: ColorsManager.grayButtonColors,
),
),
),
@ -146,38 +127,32 @@ class SettingProfilePage extends StatelessWidget {
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
const SizedBox(height: 7),
DefaultContainer(
padding: const EdgeInsets.all(20),
child: InkWell(
onTap: () async {
bool val = await Navigator.of(context).push(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => LocationSettingPage(
builder: (context) => LocationSosPage(
space: spaces!.first,
deviceId: device?.uuid ?? '',
)),
);
if (val == true) {
_bloc.add(const DeviceSettingInitialInfo());
}
},
child: Row(
child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(
SizedBox(
child: Text('Location'),
),
Row(
children: [
SizedBox(
child: BodyMedium(
text: _bloc
.deviceInfo.subspace.subspaceName,
text: 'Syncroom',
fontColor: ColorsManager.textGray,
),
),
const Icon(
Icon(
Icons.arrow_forward_ios,
size: 15,
color: ColorsManager.textGray,

View File

@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class UpDateNoteSetting extends StatelessWidget {
class SosUpdateNote extends StatelessWidget {
final Function()? cancelTab;
final Function()? confirmTab;
const UpDateNoteSetting({
const SosUpdateNote({
super.key,
required this.cancelTab,
required this.confirmTab,

View File

@ -3,10 +3,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart';
import 'package:syncrow_app/features/devices/view/device_settings/update_note.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart';
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
@ -14,130 +14,123 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class UpdatePageSetting extends StatelessWidget {
final String? deviceId;
const UpdatePageSetting({super.key, this.deviceId});
class SosUpdatePage extends StatelessWidget {
const SosUpdatePage({super.key});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Device Update',
child: BlocProvider(
create: (context) => DeviceSettingBloc(deviceId: deviceId ?? '')
..add(const DeviceSettingInitial())
..add(const DeviceSettingInitialInfo()),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) {
final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
return state is DeviceSettingLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {},
child: Column(
children: [
DefaultContainer(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 50,
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: SizedBox(
width: 200,
child: Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: const BoxDecoration(
color: ColorsManager
.primaryColor,
borderRadius:
BorderRadius.all(
Radius.circular(50))),
child: SvgPicture.asset(
Assets.checkUpdateIcon,
fit: BoxFit.fill,
height: 25,
),
title: 'Device Update',
child: BlocProvider(
create: (context) => SosBloc(sosId: '')..add(const SosInitial()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {},
child: Column(
children: [
// SizedBox(
// height: MediaQuery.of(context).size.height * 0.15,
// ),
DefaultContainer(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 50,
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: SizedBox(
width: 200,
child: Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: const BoxDecoration(
color:
ColorsManager.primaryColor,
borderRadius: BorderRadius.all(
Radius.circular(50))),
child: SvgPicture.asset(
Assets.checkUpdateIcon,
fit: BoxFit.fill,
height: 25,
),
const SizedBox(
width: 10,
),
const SizedBox(
width: 10,
),
InkWell(
onTap: () {},
child: const BodyMedium(
text: 'Automatic Update',
fontWeight: FontWeight.normal,
),
InkWell(
onTap: () {},
child: const BodyMedium(
text: 'Automatic Update',
fontWeight: FontWeight.normal,
),
),
],
),
),
],
),
trailing: Container(
width: 100,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
BodyMedium(
text: _bloc.enableUpdate
? 'true'
: 'Off',
fontColor: ColorsManager.textGray,
),
trailing: Container(
width: 100,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
const BodyMedium(
text: 'Off',
fontColor: ColorsManager.textGray,
),
Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: true,
onChanged: (value) {},
applyTheme: true,
),
Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: _bloc.enableUpdate,
onChanged: (value) {
_bloc.add(ToggleUpdateEvent(
isUpdateEnabled: value));
},
applyTheme: true,
),
),
],
),
)),
),
],
),
),
],
),
)),
),
],
),
const SizedBox(
height: 10,
),
const UpdateSosContainerWithProgressBar(
sosDescription:
'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.',
sosVersion: 'SOS v2.0.5',
),
// const UpdatedContainer(
// sosVersion: 'SOS v1.0.13',
// sosDescription: 'SOS is up to date',
// ),
),
const SizedBox(
height: 10,
),
UpdateSosContainerWithProgressBar(
sosDescription:
'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.',
sosVersion: 'SOS v2.0.5',
),
// const UpdatedContainer(
// sosVersion: 'SOS v1.0.13',
// sosDescription: 'SOS is up to date',
// ),
// const NewUpdateContainer(
// sosVersion: 'SOS v2.0.5',
// sosDescription:
// 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.',
// ),
const SizedBox(
height: 15,
),
],
));
},
),
));
// const NewUpdateContainer(
// sosVersion: 'SOS v2.0.5',
// sosDescription:
// 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.',
// ),
const SizedBox(
height: 15,
),
],
));
},
),
),
);
}
}
@ -220,7 +213,7 @@ class NewUpdateContainer extends StatelessWidget {
text: sosVersion!,
fontColor: ColorsManager.primaryTextColor,
),
SizedBox(
Container(
width: MediaQuery.of(context).size.width * 0.7,
child: BodyMedium(
text: sosDescription!,
@ -238,7 +231,7 @@ class NewUpdateContainer extends StatelessWidget {
showDialog(
context: context,
builder: (context) {
return UpDateNoteSetting(
return SosUpdateNote(
cancelTab: () {
Navigator.of(context).pop();
},
@ -313,7 +306,7 @@ class UpdateSosContainerWithProgressBar extends StatelessWidget {
),
),
LinearPercentIndicator(
barRadius: const Radius.circular(10),
barRadius: Radius.circular(10),
width: 170.0,
animation: true,
animationDuration: 1000,

View File

@ -1,377 +1,484 @@
// import 'package:flutter/material.dart';
// import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:flutter_svg/flutter_svg.dart';
// import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
// import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
// import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
// import 'package:syncrow_app/features/devices/model/device_model.dart';
// import 'package:syncrow_app/features/devices/model/sos_model.dart';
// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart';
// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart';
// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart';
// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart';
// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart';
// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart';
// import 'package:syncrow_app/features/shared_widgets/default_container.dart';
// import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
// import 'package:syncrow_app/features/shared_widgets/delete_device_dialogs.dart';
// import 'package:syncrow_app/features/shared_widgets/setting_widget.dart';
// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
// import 'package:syncrow_app/generated/assets.dart';
// import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/sos_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
// class SosSettings extends StatelessWidget {
// final DeviceModel? device;
// const SosSettings({
// super.key,
// this.device,
// });
class SosSettings extends StatelessWidget {
final DeviceModel? device;
// @override
// Widget build(BuildContext context) {
// return DefaultScaffold(
// title: 'Device Settings',
// child: BlocProvider(
// create: (context) => SosBloc(sosId: device?.uuid ?? '')
// ..add(const SosInitial())
// ..add(SosInitialDeviseInfo()),
// child: BlocBuilder<SosBloc, SosState>(
// builder: (context, state) {
// final _bloc = BlocProvider.of<SosBloc>(context);
// SosModel model =
// SosModel(batteryPercentage: 0, sosContactState: 'normal');
// if (state is LoadingNewSate) {
// model = state.sosSensor;
// } else if (state is UpdateState) {
// model = state.sensor;
// }
// return state is SosLoadingState
// ? const Center(
// child: DefaultContainer(
// width: 50,
// height: 50,
// child: CircularProgressIndicator()),
// )
// : ListView(
// children: [
// Padding(
// padding: const EdgeInsets.symmetric(
// vertical: 10,
// ),
// child: InkWell(
// onTap: () async {
// bool val = await Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => SosProfilePage(
// device: device,
// ),
// ),
// );
// if (val == true) {
// _bloc.add(SosInitialDeviseInfo());
// _bloc.add(const SosInitial());
// }
// },
// child: Stack(
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: [
// const SizedBox(height: 20),
// DefaultContainer(
// borderRadius: const BorderRadius.all(
// Radius.circular(30)),
// child: Padding(
// padding: const EdgeInsets.all(10.0),
// child: Padding(
// padding:
// const EdgeInsets.only(left: 90),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// BodyMedium(
// text: _bloc.deviceInfo.name,
// fontWeight: FontWeight.bold,
// ),
// const SizedBox(
// height: 5,
// ),
// BodySmall(
// text: _bloc.deviceInfo
// .subspace.subspaceName),
// ],
// ),
// const Icon(
// Icons.edit_outlined,
// color: ColorsManager.grayColor,
// ),
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// Positioned(
// top: 0,
// left: 20,
// child: CircleAvatar(
// radius: 40,
// backgroundColor: Colors.white,
// child: CircleAvatar(
// radius: 40,
// backgroundColor:
// Colors.white.withOpacity(0),
// child: ClipOval(
// child: SvgPicture.asset(
// Assets.sosHomeIcon,
// fit: BoxFit.contain,
// height: 80,
// ),
// )),
// ),
// ),
// ],
// ),
// ),
// ),
// const SizedBox(height: 20),
// const BodyMedium(
// text: 'Device Management',
// fontWeight: FontWeight.w700,
// fontSize: 12,
// fontColor: ColorsManager.grayColor,
// ),
// DefaultContainer(
// child: SettingWidget(
// onTap: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) =>
// SosInfoPage(device: device!)),
// );
// },
// text: 'Device Information',
// icon: Assets.infoIcon,
// ),
// ),
// const SizedBox(height: 20),
// const BodyMedium(
// text: 'Device Offline Notification',
// fontWeight: FontWeight.w700,
// fontSize: 12,
// fontColor: ColorsManager.grayColor,
// ),
// DefaultContainer(
// child: Column(
// children: [
// SettingWidget(
// value: _bloc.enableAlarm,
// onChanged: (p0) {
// context
// .read<SosBloc>()
// .add(ToggleEnableAlarmEvent(p0));
// },
// isNotification: true,
// onTap: () {},
// text: 'Offline Notification',
// icon: Assets.notificationIcon,
// ),
// ],
// ),
// ),
// const SizedBox(height: 20),
// const BodyMedium(
// text: 'Others',
// fontWeight: FontWeight.w700,
// fontSize: 12,
// fontColor: ColorsManager.grayColor,
// ),
// const SizedBox(height: 5),
// DefaultContainer(
// child: Column(
// children: [
// SettingWidget(
// onTap: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) =>
// ShareSosPage(device: device!)),
// );
// },
// text: 'Share Device',
// icon: Assets.shareIcon,
// ),
// const Divider(
// color: ColorsManager.dividerColor,
// ),
// SettingWidget(
// onTap: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) =>
// FaqSosPage(device: device!)),
// );
// },
// text: 'Device FAQ',
// icon: Assets.faqIcon,
// ),
// const Divider(
// color: ColorsManager.dividerColor,
// ),
// SettingWidget(
// onTapUpdate: () {
// showDialog(
// context: context,
// builder: (context) {
// return UpdateInfoDialog(
// cancelTab: () {
// Navigator.of(context).pop();
// },
// confirmTab: () {
// Navigator.of(context).pop();
// },
// );
// },
// );
// },
// isUpdate: true,
// onTap: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) =>
// const SosUpdatePage()),
// );
// },
// text: 'Device Update',
// icon: Assets.updateIcon,
// ),
// ],
// ),
// ),
// const SizedBox(height: 20),
// InkWell(
// onTap: () {
// showModalBottomSheet(
// context: context,
// builder: (BuildContext context) {
// return Container(
// height: 200,
// padding: const EdgeInsets.all(16.0),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// const BodyMedium(
// text: 'Remove Device',
// fontWeight: FontWeight.w700,
// fontSize: 16,
// fontColor: ColorsManager.red,
// ),
// const SizedBox(height: 10),
// const SizedBox(
// width: 250,
// child: Divider(
// color: ColorsManager.dividerColor,
// ),
// ),
// const SizedBox(height: 10),
// Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// InkWell(
// onTap: () {
// showDialog(
// context: context,
// builder: (context) {
// return DisconnectDeviceDialog(
// cancelTab: () {
// Navigator.of(context).pop();
// },
// confirmTab: () {
// Navigator.of(context).pop();
// },
// );
// },
// );
// },
// child: const BodyMedium(
// text: 'Disconnect Device',
// fontWeight: FontWeight.w400,
// fontSize: 15,
// fontColor:
// ColorsManager.textPrimaryColor,
// ),
// ),
// const Icon(
// Icons.keyboard_arrow_right,
// color: ColorsManager.textGray,
// )
// ],
// ),
// const SizedBox(height: 20),
// Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// InkWell(
// onTap: () {
// showDialog(
// context: context,
// builder: (context) {
// return DisconnectWipeData(
// cancelTab: () {
// Navigator.of(context).pop();
// },
// confirmTab: () {
// _bloc.add(
// DeleteDeviceEvent());
// },
// );
// },
// );
// },
// child: const BodyMedium(
// text:
// 'Disconnect Device and Wipe Data',
// fontWeight: FontWeight.w400,
// fontSize: 15,
// fontColor:
// ColorsManager.textPrimaryColor,
// ),
// ),
// const Icon(
// Icons.keyboard_arrow_right,
// color: ColorsManager.textGray,
// )
// ],
// ),
// ],
// ),
// );
// },
// );
// },
// child: const Center(
// child: BodyMedium(
// text: 'Remove Device',
// fontWeight: FontWeight.w400,
// fontSize: 15,
// fontColor: ColorsManager.red,
// ),
// ),
// ),
// ],
// );
// },
// ),
// ),
// );
// }
// }
const SosSettings({super.key, this.device});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Device Settings',
child: BlocProvider(
create: (context) =>
SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()),
child: BlocBuilder<SosBloc, SosState>(
builder: (context, state) {
final sensor = BlocProvider.of<SosBloc>(context);
SosModel model =
SosModel(batteryPercentage: 0, sosContactState: 'normal');
if (state is LoadingNewSate) {
model = state.sosSensor;
} else if (state is UpdateState) {
model = state.sensor;
}
return state is SosLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
sensor.add(const SosInitial());
},
child: ListView(
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SosProfilePage(),
),
);
},
child: Stack(
children: [
const Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
SizedBox(height: 20),
DefaultContainer(
borderRadius:
BorderRadius.all(Radius.circular(30)),
child: Padding(
padding: EdgeInsets.all(10.0),
child: Padding(
padding: EdgeInsets.only(left: 90),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
BodyMedium(
text: 'SOS',
fontWeight: FontWeight.bold,
),
SizedBox(
height: 5,
),
BodySmall(
text: "Room: Syncrow"),
],
),
Icon(
Icons.edit_outlined,
color: ColorsManager.grayColor,
),
],
),
),
),
),
],
),
Positioned(
top: 0,
left: 20,
child: CircleAvatar(
radius: 40,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 40,
backgroundColor: Colors.grey,
child: ClipOval(
child: SvgPicture.asset(
Assets.sosProfileIcon,
fit: BoxFit.fill,
),
),
),
),
),
],
),
),
),
const SizedBox(height: 20),
const BodyMedium(
text: 'Device Management',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
DefaultContainer(
child: SettingWidget(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SosInfoPge()),
);
},
text: 'Device Information',
icon: Assets.infoIcon,
),
),
const SizedBox(height: 20),
const BodyMedium(
text: 'Device Offline Notification',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
DefaultContainer(
child: Column(
children: [
SettingWidget(
onChanged: (p0) {},
isNotification: true,
onTap: () {},
text: 'Offline Notification',
icon: Assets.notificationIcon,
),
],
),
),
const SizedBox(height: 20),
const BodyMedium(
text: 'Others',
fontWeight: FontWeight.w700,
fontSize: 12,
fontColor: ColorsManager.grayColor,
),
const SizedBox(height: 5),
DefaultContainer(
child: Column(
children: [
SettingWidget(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
ShareSosPage(device: device!)),
);
},
text: 'Share Device',
icon: Assets.shareIcon,
),
const Divider(
color: ColorsManager.dividerColor,
),
SettingWidget(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
FaqSosPage(device: device!)),
);
},
text: 'Device FAQ',
icon: Assets.faqIcon,
),
const Divider(
color: ColorsManager.dividerColor,
),
SettingWidget(
onTapUpdate: () {
showDialog(
context: context,
builder: (context) {
return UpdateInfoDialog(
cancelTab: () {
Navigator.of(context).pop();
},
confirmTab: () {
// context
// .read<
// CreateSceneBloc>()
// .add(DeleteSceneEvent(
// sceneId: sceneId,
// unitUuid: HomeCubit
// .getInstance()
// .selectedSpace!
// .id!,
// ));
Navigator.of(context).pop();
},
);
},
);
},
isUpdate: true,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
const SosUpdatePage()),
);
},
text: 'Device Update',
icon: Assets.updateIcon,
),
],
),
),
const SizedBox(height: 20),
InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodyMedium(
text: 'Remove Device',
fontWeight: FontWeight.w700,
fontSize: 16,
fontColor: ColorsManager.red,
),
const SizedBox(height: 10),
const SizedBox(
width: 250,
child: Divider(
color: ColorsManager.dividerColor,
),
),
const SizedBox(height: 10),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
showDialog(
context: context,
builder: (context) {
return DisconnectDeviceDialog(
cancelTab: () {
Navigator.of(context)
.pop();
},
confirmTab: () {
// context
// .read<
// CreateSceneBloc>()
// .add(DeleteSceneEvent(
// sceneId: sceneId,
// unitUuid: HomeCubit
// .getInstance()
// .selectedSpace!
// .id!,
// ));
Navigator.of(context)
.pop();
},
);
},
);
},
child: const BodyMedium(
text: 'Disconnect Device',
fontWeight: FontWeight.w400,
fontSize: 15,
fontColor: ColorsManager
.textPrimaryColor,
),
),
const Icon(
Icons.keyboard_arrow_right,
color: ColorsManager.textGray,
)
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
showDialog(
context: context,
builder: (context) {
return DisconnectWipeData(
cancelTab: () {
Navigator.of(context)
.pop();
},
confirmTab: () {
// context
// .read<
// CreateSceneBloc>()
// .add(DeleteSceneEvent(
// sceneId: sceneId,
// unitUuid: HomeCubit
// .getInstance()
// .selectedSpace!
// .id!,
// ));
Navigator.of(context)
.pop();
},
);
},
);
},
child: const BodyMedium(
text:
'Disconnect Device and Wipe Data',
fontWeight: FontWeight.w400,
fontSize: 15,
fontColor: ColorsManager
.textPrimaryColor,
),
),
const Icon(
Icons.keyboard_arrow_right,
color: ColorsManager.textGray,
)
],
),
],
),
);
},
);
},
child: const Center(
child: BodyMedium(
text: 'Remove Device',
fontWeight: FontWeight.w400,
fontSize: 15,
fontColor: ColorsManager.red,
),
),
),
],
),
);
},
),
),
);
}
}
class SettingWidget extends StatelessWidget {
final String? text;
final bool? isUpdate;
final bool? isNotification;
final String? icon;
final Function()? onTap;
final Function()? onTapUpdate;
final Function(bool)? onChanged;
const SettingWidget(
{super.key,
this.text,
this.icon,
this.onTap,
this.isUpdate,
this.onChanged,
this.isNotification = false,
this.onTapUpdate});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
padding: EdgeInsets.all(8),
decoration: const BoxDecoration(
color: ColorsManager.primaryColor,
borderRadius: BorderRadius.all(Radius.circular(20))),
child: SvgPicture.asset(
icon!,
fit: BoxFit.none,
height: 30,
),
),
),
const SizedBox(
width: 8,
),
Expanded(
flex: isUpdate == true ? 5 : 10,
child: BodyMedium(
text: text!,
fontSize: 15,
fontWeight: FontWeight.w400,
)),
],
),
),
isUpdate == true
? InkWell(
onTap: onTapUpdate,
child: const BodyMedium(
text: '1 Update Available',
fontSize: 13,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blueColor,
),
)
: SizedBox(),
isNotification == false
? const Icon(
Icons.arrow_forward_ios,
color: ColorsManager.graysColor,
size: 20,
)
: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: true,
onChanged: onChanged,
applyTheme: true,
),
),
],
),
);
}
}

View File

@ -99,9 +99,6 @@ mixin SceneLogicHelper {
}
if (task.code == CreateSceneEnum.smartSceneSelect.name) {
return CreateSceneAction(
actionType: task.operationName.toLowerCase() == 'automation'
? 'automation'
: 'scene',
entityId: actions[index].deviceId,
actionExecutor: actions[index].functionValue,
executorProperty: null);
@ -176,24 +173,21 @@ mixin SceneLogicHelper {
}
}
Widget getTheCorrectDialogBody(
SceneStaticFunction taskItem, dynamic functionValue,
Widget getTheCorrectDialogBody(SceneStaticFunction taskItem, dynamic functionValue,
{required bool isAutomation}) {
if (taskItem.operationDialogType == OperationDialogType.temperature) {
return AlertDialogTemperatureBody(
taskItem: taskItem,
functionValue: functionValue ?? taskItem.functionValue,
);
} else if ((taskItem.operationDialogType ==
OperationDialogType.countdown) ||
} else if ((taskItem.operationDialogType == OperationDialogType.countdown) ||
(taskItem.operationDialogType == OperationDialogType.delay)) {
return AlertDialogCountdown(
durationValue: taskItem.functionValue ?? 0,
functionValue: functionValue ?? taskItem.functionValue,
function: taskItem,
);
} else if (taskItem.operationDialogType ==
OperationDialogType.integerSteps) {
} else if (taskItem.operationDialogType == OperationDialogType.integerSteps) {
return AlertDialogSliderSteps(
taskItem: taskItem,
functionValue: functionValue ?? taskItem.functionValue,

View File

@ -95,25 +95,21 @@ class CreateSceneModel {
class CreateSceneAction {
String entityId;
String? actionType;
String actionExecutor;
CreateSceneExecutorProperty? executorProperty;
CreateSceneAction({
this.actionType,
required this.entityId,
required this.actionExecutor,
required this.executorProperty,
});
CreateSceneAction copyWith({
String? actionType,
String? entityId,
String? actionExecutor,
CreateSceneExecutorProperty? executorProperty,
}) {
return CreateSceneAction(
actionType: actionType,
entityId: entityId ?? this.entityId,
actionExecutor: actionExecutor ?? this.actionExecutor,
executorProperty: executorProperty ?? this.executorProperty,
@ -129,7 +125,6 @@ class CreateSceneAction {
};
} else {
return {
"actionType": actionType,
'entityId': entityId,
'actionExecutor': actionExecutor,
};

View File

@ -1,94 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class SettingWidget extends StatelessWidget {
final String? text;
final bool? isUpdate;
final bool? value;
final bool? isNotification;
final String? icon;
final Function()? onTap;
final Function()? onTapUpdate;
final Function(bool)? onChanged;
const SettingWidget(
{super.key,
this.text,
this.icon,
this.value,
this.onTap,
this.isUpdate,
this.onChanged,
this.isNotification = false,
this.onTapUpdate});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.all(8),
decoration: const BoxDecoration(
color: ColorsManager.primaryColor,
borderRadius: BorderRadius.all(Radius.circular(20))),
child: SvgPicture.asset(
icon!,
fit: BoxFit.none,
height: 30,
),
),
),
const SizedBox(
width: 8,
),
Expanded(
flex: isUpdate == true ? 5 : 10,
child: BodyMedium(
text: text!,
fontSize: 15,
fontWeight: FontWeight.w400,
)),
],
),
),
isUpdate == true
? InkWell(
onTap: onTapUpdate,
child: const BodyMedium(
text: '1 Update Available',
fontSize: 13,
fontWeight: FontWeight.w400,
fontColor: ColorsManager.blueColor,
),
)
: const SizedBox(),
isNotification == false
? const Icon(
Icons.arrow_forward_ios,
color: ColorsManager.graysColor,
size: 20,
)
: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: value!,
onChanged: onChanged,
applyTheme: true,
),
),
],
),
);
}
}

View File

@ -1091,6 +1091,7 @@ class Assets {
static const String powerClampIcon = "assets/icons/power_clamp.svg";
static const String automationIcon = "assets/icons/automation_ic.svg";
//sos
static const String redSos = "assets/icons/red_sos.svg";
static const String greenSos = "assets/icons/green_sos.svg";
static const String emptyLog = "assets/icons/empty_log.svg";
@ -1105,24 +1106,8 @@ class Assets {
static const String updateIcon = "assets/icons/update_icon.svg";
static const String emptyUpdateIcon = "assets/icons/empty_update_icon.svg";
static const String checkUpdateIcon = "assets/icons/check_update_icon.svg";
static const String sosDevice = "assets/icons/sos_device.svg";
static const String editNameSosIcon = "assets/icons/edit_name_sos_icon.svg";
static const String switchOn = "assets/icons/switch_on.svg";
static const String switchOff = "assets/icons/switch_off.svg";
static const String backlightIcon = "assets/icons/backlight_icon.svg";
static const String addSwitchIcon = "assets/icons/add_switch_icon.svg";
static const String addSceneIcon = "assets/icons/add_scene_icon.svg";
static const String removeSceneIcon = "assets/icons/remove_scene_icon.svg";
static const String tapRunIcon = "assets/icons/tap_run_icon.svg";
static const String createGroupIcon = "assets/icons/create_group_icon.svg";
static const String sixSceneIcon = "assets/icons/six_scene_icon.svg";
static const String minusIcon = "assets/icons/minus_icon.svg";
static const String addDevicesIcon = "assets/icons/add_devices_icon.svg";
static const String fourSceneIcon = "assets/icons/four_scene_icon.svg";
static const String fourSceneHomeIcon =
"assets/icons/four_scene_home_icon.svg";
static const String sixSceneHomeIcon = "assets/icons/six_scene_home_icon.svg";
static const String editDeviceNameIcon =
"assets/icons/edit_device_name_icon.svg";
static const String sosHomeIcon = "assets/icons/sos_home_icon.svg";
static const String editNameSetting = "assets/icons/edit_name_setting.svg";
}

View File

@ -59,11 +59,11 @@ abstract class ApiEndpoints {
//GET
static const String unitByUuid = '/unit/';
static const String listSubspace =
'projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/subspaces';
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces';
static const String unitParent = '/unit/parent/{unitUuid}';
static const String unitUser = '/unit/user/';
static const String invitationCode =
'projects/{projectUuid}/communities/{communityUuid}/spaces/{unitUuid}/invitation-code';
'/communities/{communityUuid}/spaces/{unitUuid}/invitation-code';
//PUT
static const String renameUnit = '/unit/{unitUuid}';
@ -71,7 +71,7 @@ abstract class ApiEndpoints {
//Subspace Module
//POST
static const String addSubSpace =
'projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/subspaces';
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces';
///Room Module
//POST
@ -88,7 +88,7 @@ abstract class ApiEndpoints {
//GET
static const String userSpaces = '/user/{userUuid}/spaces';
static const String spaceDevices =
'projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
'/communities/{communityUuid}/spaces/{spaceUuid}/devices';
///Group Module
//POST
@ -117,7 +117,7 @@ abstract class ApiEndpoints {
//GET
static const String deviceByRoom =
'projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices';
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices';
static const String deviceByUuid = '/device/{deviceUuid}';
static const String deviceFunctions = '/device/{deviceUuid}/functions';
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
@ -135,7 +135,7 @@ abstract class ApiEndpoints {
static const String editDevicePermission = '/device-permission/edit/{userId}';
static const String assignDeviceToRoom =
'projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices/{deviceUuid}';
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices/{deviceUuid}';
/// Scene & Automation API ////////////////////
/// POST
@ -145,7 +145,7 @@ abstract class ApiEndpoints {
/// GET
static const String getUnitScenes =
'projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
'/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
static const String getScene = '/scene/tap-to-run/{sceneId}';
static const String getIconScene = '/scene/icon';
@ -213,12 +213,4 @@ abstract class ApiEndpoints {
'/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
static const String controlBatch = '/device/control/batch';
static const String statusBatch = '/device/status/batch';
static const String deviceScene = '/device/{deviceUuid}/scenes';
static const String fourSceneByName =
'/device/{deviceUuid}/scenes?switchName={switchName}';
static const String resetDevice = '/factory/reset/{deviceUuid}';
static const String unAssignScenesDevice =
'/device/{deviceUuid}/scenes?switchName={switchName}';
}

View File

@ -8,7 +8,6 @@ import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/function_model.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import '../../features/devices/model/create_temporary_password_model.dart';
class DevicesAPI {
@ -32,22 +31,6 @@ class DevicesAPI {
}
}
static Future<Map<String, dynamic>> putDeviceName(
{required String deviceId, required String deviceName}) async {
try {
final response = await _httpService.put(
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
body: {"deviceName": deviceName},
expectedResponseModel: (json) {
return json;
},
);
return response;
} catch (e) {
rethrow;
}
}
static Future<Map<String, dynamic>> controlDevice(
DeviceControlModel controlModel, String deviceId) async {
try {
@ -82,7 +65,7 @@ class DevicesAPI {
showServerMessage: false,
expectedResponseModel: (json) => DevicesCategoryModel.fromJsonList(json),
);
return response;
}
@ -138,62 +121,6 @@ class DevicesAPI {
return response;
}
static Future getDeviceSceneInfo(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
});
return response;
}
static Future getSceneBySwitchName(
{String? deviceId, String? switchName}) async {
final response = await _httpService.get(
path: ApiEndpoints.fourSceneByName
.replaceAll('{deviceUuid}', deviceId!)
.replaceAll('{switchName}', switchName!),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
});
return response;
}
static Future postDeviceSceneInfo({
String? switchName,
String? sceneUuid,
String? deviceId,
String? spaceUuid,
}) async {
final response = await _httpService.post(
path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!),
body: jsonEncode(
{
"switchName": switchName,
"sceneUuid": sceneUuid,
"spaceUuid": spaceUuid
},
),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
});
return response;
}
static Future getDeviceInfo(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
print('object-*-*-*${json}');
return json;
});
return response;
}
static Future<List<DeviceModel>> getDeviceByGroupName(
String unitId, String groupName) async {
final response = await _httpService.get(
@ -225,8 +152,7 @@ class DevicesAPI {
final String path = ApiEndpoints.deviceByRoom
.replaceAll('{communityUuid}', communityUuid)
.replaceAll('{spaceUuid}', spaceUuid)
.replaceAll('{subSpaceUuid}', roomId)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{subSpaceUuid}', roomId);
final response = await _httpService.get(
path: path,
@ -513,36 +439,4 @@ class DevicesAPI {
);
return response;
}
static Future resetDevise({
String? devicesUuid,
}) async {
final response = await _httpService.post(
path: ApiEndpoints.resetDevice.replaceAll('{deviceUuid}', devicesUuid!),
showServerMessage: false,
body: {
"devicesUuid": [devicesUuid]
},
expectedResponseModel: (json) {
return json;
},
);
return response;
}
static Future unAssignScenesDevice({
String? deviceUuid,
String? switchName,
}) async {
final response = await _httpService.delete(
path: ApiEndpoints.unAssignScenesDevice
.replaceAll('{deviceUuid}', deviceUuid!)
.replaceAll('{switchName}', switchName!),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
},
);
return response;
}
}

View File

@ -1,6 +1,5 @@
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
class HomeCreation {
static final HTTPService _httpService = HTTPService();
@ -149,8 +148,7 @@ class HomeCreation {
try {
final fullPath = ApiEndpoints.addSubSpace
.replaceAll('{communityUuid}', communityId)
.replaceAll('{spaceUuid}', spaceId)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{spaceUuid}', spaceId);
final response = await _httpService.post(
path: fullPath,
body: body,

View File

@ -4,7 +4,6 @@ import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
class HomeManagementAPI {
static final HTTPService _httpService = HTTPService();
@ -39,9 +38,7 @@ class HomeManagementAPI {
// Ensure both placeholders are replaced
final path = ApiEndpoints.spaceDevices
.replaceAll('{communityUuid}', communityUuid)
.replaceAll('{spaceUuid}', spaceUuid)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceAll('{spaceUuid}', spaceUuid);
await _httpService.get(
path: path,
showServerMessage: false,
@ -81,7 +78,7 @@ class HomeManagementAPI {
}
}
static Future<Map<String, dynamic>> unAssignDeviceToRoom(String communityId,
static Future<Map<String, dynamic>> unAssignDeviceToRoom(String communityId,
String spaceId, String subSpaceId, String deviceId) async {
try {
final response = await _httpService.delete(
@ -89,8 +86,7 @@ class HomeManagementAPI {
.replaceAll('{communityUuid}', communityId)
.replaceAll('{spaceUuid}', spaceId)
.replaceAll('{subSpaceUuid}', subSpaceId)
.replaceAll('{deviceUuid}', deviceId)
.replaceAll('{projectUuid}', TempConst.projectId),
.replaceAll('{deviceUuid}', deviceId),
expectedResponseModel: (json) {
return json;
},
@ -100,4 +96,5 @@ class HomeManagementAPI {
rethrow;
}
}
}

View File

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:syncrow_app/features/scene/model/create_automation_model.dart';
import 'package:syncrow_app/features/scene/model/create_scene_model.dart';
import 'package:syncrow_app/features/scene/model/icon_model.dart';
@ -6,7 +8,6 @@ import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/features/scene/model/update_automation.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
class SceneApi {
static final HTTPService _httpService = HTTPService();
@ -56,8 +57,7 @@ class SceneApi {
final response = await _httpService.get(
path: ApiEndpoints.getUnitScenes
.replaceAll('{spaceUuid}', unitId)
.replaceAll('{communityUuid}', communityId)
.replaceAll('{projectUuid}', TempConst.projectId),
.replaceAll('{communityUuid}', communityId),
queryParameters: {'showInHomePage': showInDevice},
showServerMessage: false,
expectedResponseModel: (json) {

View File

@ -4,7 +4,6 @@ import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
class SpacesAPI {
static final HTTPService _httpService = HTTPService();
@ -36,8 +35,7 @@ class SpacesAPI {
// Construct the API path
final path = ApiEndpoints.listSubspace
.replaceFirst('{communityUuid}', communityId)
.replaceFirst('{spaceUuid}', spaceId)
.replaceAll('{projectUuid}', TempConst.projectId);
.replaceFirst('{spaceUuid}', spaceId);
final response = await _httpService.get(
path: path,
@ -62,15 +60,12 @@ class SpacesAPI {
}
}
//factory/reset/{deviceUuid}
static Future<String> generateInvitationCode(
String unitId, String communityId) async {
final response = await _httpService.get(
path: ApiEndpoints.invitationCode
.replaceAll('{unitUuid}', unitId)
.replaceAll('{communityUuid}', communityId)
.replaceAll('{projectUuid}', TempConst.projectId),
.replaceAll('{communityUuid}', communityId),
showServerMessage: false,
expectedResponseModel: (json) {
if (json != null && json['data'] != null) {

View File

@ -1,3 +0,0 @@
class TempConst {
static const projectId = '0e62577c-06fa-41b9-8a92-99a21fbaf51c';
}

View File

@ -56,9 +56,8 @@ enum DeviceType {
GarageDoor,
WaterLeak,
PC,
FourScene,
SixScene,
SOS,
Other,
}
@ -91,11 +90,8 @@ Map<String, DeviceType> devicesTypesMap = {
"GD": DeviceType.GarageDoor,
"WL": DeviceType.WaterLeak,
"PC": DeviceType.PC,
"4S": DeviceType.FourScene,
"6S": DeviceType.SixScene,
"SOS": DeviceType.SOS,
};
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
DeviceType.AC: [
FunctionModel(
@ -516,86 +512,6 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
"range": ["unclosed_time", "close_time_alarm", "none"]
})),
],
DeviceType.FourScene: [
FunctionModel(
code: 'scene_1',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_2',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_3',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_4',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_id_group_id',
type: functionTypesMap['Raw'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'switch_backlight',
type: functionTypesMap['Enum'],
values: ValueModel.fromJson({})),
],
DeviceType.SixScene: [
FunctionModel(
code: 'scene_1',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_2',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_3',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_4',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_5',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_6',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({
"range": ["scene"]
})),
FunctionModel(
code: 'scene_id_group_id',
type: functionTypesMap['Raw'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'switch_backlight',
type: functionTypesMap['Enum'],
values: ValueModel.fromJson({})),
],
DeviceType.SOS: [
FunctionModel(
code: 'contact_state',

View File

@ -5,7 +5,7 @@ description: This is the mobile application project, developed with Flutter for
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.9+45
version: 1.0.7+40
environment:
sdk: ">=3.0.6 <4.0.0"
@ -46,7 +46,7 @@ dependencies:
device_info_plus: ^10.1.0
fl_chart: ^0.69.0
firebase_database: ^10.5.7
percent_indicator: ^4.2.3
percent_indicator: ^4.0.1
dev_dependencies: