Compare commits

..

99 Commits

Author SHA1 Message Date
391d6349cc Fixed the assets order 2024-11-05 15:54:48 +04:00
9c873fb0c5 fixed icon assets issue 2024-11-05 15:53:31 +04:00
e9615cd351 Fixed show in device bug 2024-11-05 12:52:11 +04:00
52f6be3db0 updated add to room, and verify to space 2024-11-05 12:27:27 +04:00
34536e6584 updated invitation code api 2024-11-05 11:01:49 +04:00
7d51ca1f12 Fixed bugs in automation 2024-11-05 00:52:38 +04:00
ff31c54e7b reformat 2024-11-04 17:59:55 +04:00
944de7b373 reformat 2024-11-04 17:45:29 +04:00
ab4f8c593d revert 2024-11-04 10:32:13 +04:00
977fd12721 podfile revert 2024-11-04 10:30:50 +04:00
e4a3d4c50b delete scene 2024-11-04 10:28:16 +04:00
29f82945a6 revert back 2024-11-04 10:19:36 +04:00
87a4a88417 fixed automation 2024-11-02 23:10:24 +04:00
dcccc4db3a create subspace 2024-10-31 11:30:35 +04:00
36e5df38ee Merge branch 'dev' of https://github.com/SyncrowIOT/syncrow-app into feat/refactor 2024-10-31 10:45:08 +04:00
7571e35a70 revert 2024-10-31 10:40:29 +04:00
995fd8d0a6 revert 2024-10-31 10:40:05 +04:00
b7b48006af revert config 2024-10-31 10:38:15 +04:00
ea202812cd revert back 2024-10-31 10:35:26 +04:00
79f224f481 revert back env 2024-10-31 10:34:39 +04:00
80d2651370 scene and automation has been updated 2024-10-31 10:19:38 +04:00
7071f50d49 auth_change 2024-10-31 08:35:32 +03:00
13a4bf25b3 added unit devices 2024-10-30 19:16:10 +04:00
f6a12f2e92 Merge pull request #62 from SyncrowIOT/password_changes
password_changes&_routine_changes
2024-10-30 14:23:11 +03:00
5d32fc1213 Resend 2024-10-30 12:18:16 +03:00
bfd9c557ce remove_real_time 2024-10-30 11:56:12 +03:00
5c65bac076 removed logs 2024-10-30 12:27:31 +04:00
489789da0a fixed issues in space 2024-10-30 11:04:36 +04:00
d025da6daf fixed space 2024-10-30 09:56:57 +04:00
5a7ed3ec7c subspace model added 2024-10-29 18:44:41 +04:00
1558996891 models 2024-10-29 18:41:59 +04:00
ef232e9cd5 password_changes&_routine_changes 2024-10-29 17:21:31 +03:00
a1b8c79ce4 Merge pull request #61 from SyncrowIOT/power_clamp_issue
power_clamp_issue&search_issue
2024-10-29 11:10:44 +03:00
70d8bae19d change_size 2024-10-29 11:08:29 +03:00
021f40b8b3 Merged with dev 2024-10-29 10:58:02 +03:00
13f244ff19 power_clamp_issue&search_issue 2024-10-28 17:08:49 +03:00
bcc31d53a1 Enabled real time data 2024-10-28 17:03:05 +03:00
3adb84125a Merge pull request #60 from SyncrowIOT/icon_settings
Icon settings
2024-10-28 16:52:22 +03:00
3d56f33ec3 Implemented tab to run setting 2024-10-28 16:45:59 +03:00
20fdfdde87 icon_settings 2024-10-27 17:21:35 +03:00
7fed2f17af icon_settings 2024-10-27 17:21:13 +03:00
769be41855 con setting 2024-10-27 17:16:37 +03:00
d4d7ced585 Merge pull request #59 from SyncrowIOT/power_clamp
Power clamp
2024-10-27 14:03:24 +03:00
2be5d0e164 search_icon 2024-10-27 10:56:21 +03:00
5844ea429b power_clamp_icon 2024-10-23 16:58:43 +03:00
34762dee6e power_clamp_chart_functionality 2024-10-23 16:40:12 +03:00
600ed7992d power_clamp_chart_functionality 2024-10-23 16:38:40 +03:00
91ba2bad78 power_clamp 2024-10-22 13:21:15 +03:00
9e678fddaf power_clamp 2024-10-22 10:13:12 +03:00
5b1fd3bdd8 power+clamp 2024-10-22 10:10:57 +03:00
b7b326969a power_clamp 2024-10-20 16:57:13 +03:00
aa27ecf908 power clamp 2024-10-17 16:04:11 +03:00
82ddc499ac power_chart_changes 2024-10-16 16:37:33 +03:00
ab66142568 search 2024-10-16 16:30:04 +03:00
e0dbbd67d1 static power clamp 2024-10-14 16:14:17 +03:00
0e6b83d9f5 Fixed design issues 2024-10-10 14:29:53 +03:00
5f1c4c5371 Updated the error response body 2024-10-10 13:05:48 +03:00
6efb6dd508 Merge pull request #57 from SyncrowIOT/water_leak
Water leak
2024-10-10 12:52:04 +03:00
8c3df584db pubspec 2024-10-10 10:15:59 +03:00
40ee207623 bugs fixes 2024-10-10 10:00:48 +03:00
82f08ddcd8 garage size 2024-10-09 15:22:11 +03:00
465a2e3108 curtain wizard & bugs fixes 2024-10-09 14:58:08 +03:00
e0049c0aec curtain wizard 2024-10-08 17:02:24 +03:00
f2172bd6e8 garage Alarm 2024-10-08 13:06:32 +03:00
e5af727144 remove real time 2024-10-08 11:00:03 +03:00
978e77c167 remove socket from water heater 2024-10-08 10:27:05 +03:00
4916961d49 garage door Schedule 2024-10-08 10:17:32 +03:00
c8e0aa2aa8 garage door schedule 2024-10-08 10:15:53 +03:00
75b3036e03 water leak 2024-10-08 10:11:08 +03:00
754d869fac water leak 2024-10-07 16:53:50 +03:00
1f904e107a Merge pull request #56 from SyncrowIOT/garage_door
Garage door
2024-10-07 15:28:32 +03:00
b89053c1fb fiz wizard issue 2024-10-07 15:24:06 +03:00
281414ac41 garage wizard 2024-10-07 10:29:42 +03:00
208fbd63f3 garage door wizard 2024-10-07 10:26:08 +03:00
3454f0e28d Updated the curtain design 2024-10-07 01:40:16 +03:00
2d54d52061 Updated the curtain desgin and removed unused code 2024-10-06 22:30:28 +03:00
4b45257aff garage door 2024-10-06 16:59:28 +03:00
8476b51049 garage door 2024-10-06 16:49:36 +03:00
5e046b1deb garage door 2024-10-06 16:48:17 +03:00
487c7c5514 Merge pull request #55 from SyncrowIOT/SP-630
Sp 630
2024-10-03 13:12:44 +03:00
d9761168e6 bugs fixes 2024-10-03 12:46:56 +03:00
cc7af3e4e6 wizard 2024-10-02 13:26:25 +03:00
b5af6add35 touch wizard 1gt and 2 gt and 3gt 2024-10-02 13:02:29 +03:00
0d5492d626 three touch 2024-10-01 17:01:50 +03:00
908533dc9e tow touch and three touch 2024-10-01 16:33:11 +03:00
d75d438106 two touch & three touch 2024-10-01 16:24:36 +03:00
b8b6ec67c7 setting 2024-09-30 17:30:16 +03:00
fed39b7198 setting 2024-09-30 17:02:31 +03:00
5030b3f313 one touch 2024-09-29 16:35:24 +03:00
c4ff19d471 one touch 2024-09-29 16:06:05 +03:00
e1cd9e55c2 Merge pull request #54 from SyncrowIOT/SP-496
Sp 496
2024-09-29 12:08:13 +03:00
3082148e8c Bug fixes 2 2024-09-29 12:03:58 +03:00
2fb18965f4 Bug fixes 2024-09-29 01:52:17 +03:00
8d784f1e95 fixes 2024-09-27 16:58:09 +03:00
bc1b92cd5c fixes 2024-09-26 16:47:19 +03:00
6e32f30970 fixes 2024-09-26 16:36:54 +03:00
781522d4b6 fixes 2024-09-26 16:36:23 +03:00
4e345db842 one gang wizard &two Gang wizard & wh wizard 2024-09-26 16:26:39 +03:00
8508995108 Merge pull request #53 from SyncrowIOT/491
491
2024-09-24 11:51:09 +03:00
213 changed files with 18525 additions and 2305 deletions

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"cSpell.words": [
"Scheduleapp"
]
}

View File

@ -18,6 +18,7 @@
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">

View File

@ -0,0 +1,5 @@
<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="#D1D1D1"/>
<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="#A0A0A0"/>
<path opacity="0.6" d="M20.875 19.2411V20.7304C20.875 20.9746 20.7996 21.1767 20.7014 21.3067C20.6035 21.4364 20.5053 21.4715 20.4375 21.4715H16.3125C16.2447 21.4715 16.1465 21.4364 16.0486 21.3067C15.9504 21.1767 15.875 20.9746 15.875 20.7304V19.2411C15.875 18.9969 15.9504 18.7949 16.0486 18.6649C16.1465 18.5352 16.2447 18.5 16.3125 18.5H20.4375C20.5053 18.5 20.6035 18.5352 20.7014 18.6649C20.7996 18.7949 20.875 18.9969 20.875 19.2411Z" stroke="#023DFE" stroke-opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,6 @@
<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="#D1D1D1"/>
<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="#A0A0A0"/>
<path opacity="0.6" d="M16.5 19.2411V20.7304C16.5 20.9746 16.4246 21.1767 16.3264 21.3067C16.2285 21.4364 16.1303 21.4715 16.0625 21.4715H11.9375C11.8697 21.4715 11.7715 21.4364 11.6736 21.3067C11.5754 21.1767 11.5 20.9746 11.5 20.7304V19.2411C11.5 18.9969 11.5754 18.7949 11.6736 18.6649C11.7715 18.5352 11.8697 18.5 11.9375 18.5H16.0625C16.1303 18.5 16.2285 18.5352 16.3264 18.6649C16.4246 18.7949 16.5 18.9969 16.5 19.2411Z" stroke="#023DFE" stroke-opacity="0.6"/>
<path opacity="0.6" d="M26.5 19.2411V20.7304C26.5 20.9746 26.4246 21.1767 26.3264 21.3067C26.2285 21.4364 26.1303 21.4715 26.0625 21.4715H21.9375C21.8697 21.4715 21.7715 21.4364 21.6736 21.3067C21.5754 21.1767 21.5 20.9746 21.5 20.7304V19.2411C21.5 18.9969 21.5754 18.7949 21.6736 18.6649C21.7715 18.5352 21.8697 18.5 21.9375 18.5H26.0625C26.1303 18.5 26.2285 18.5352 26.3264 18.6649C26.4246 18.7949 26.5 18.9969 26.5 19.2411Z" stroke="#023DFE" stroke-opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,7 @@
<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="#D1D1D1"/>
<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="#A0A0A0"/>
<path opacity="0.6" d="M10.5 19.2411V20.7304C10.5 20.9746 10.4246 21.1767 10.3264 21.3067C10.2285 21.4364 10.1303 21.4715 10.0625 21.4715H5.9375C5.86973 21.4715 5.77153 21.4364 5.67355 21.3067C5.57536 21.1767 5.5 20.9746 5.5 20.7304V19.2411C5.5 18.9969 5.57536 18.7949 5.67355 18.6649C5.77153 18.5352 5.86973 18.5 5.9375 18.5H10.0625C10.1303 18.5 10.2285 18.5352 10.3264 18.6649C10.4246 18.7949 10.5 18.9969 10.5 19.2411Z" stroke="#023DFE" stroke-opacity="0.6"/>
<path opacity="0.6" d="M20.5 19.2411V20.7304C20.5 20.9746 20.4246 21.1767 20.3264 21.3067C20.2285 21.4364 20.1303 21.4715 20.0625 21.4715H15.9375C15.8697 21.4715 15.7715 21.4364 15.6736 21.3067C15.5754 21.1767 15.5 20.9746 15.5 20.7304V19.2411C15.5 18.9969 15.5754 18.7949 15.6736 18.6649C15.7715 18.5352 15.8697 18.5 15.9375 18.5H20.0625C20.1303 18.5 20.2285 18.5352 20.3264 18.6649C20.4246 18.7949 20.5 18.9969 20.5 19.2411Z" stroke="#023DFE" stroke-opacity="0.6"/>
<path opacity="0.6" d="M30.5 19.2411V20.7304C30.5 20.9746 30.4246 21.1767 30.3264 21.3067C30.2285 21.4364 30.1303 21.4715 30.0625 21.4715H25.9375C25.8697 21.4715 25.7715 21.4364 25.6736 21.3067C25.5754 21.1767 25.5 20.9746 25.5 20.7304V19.2411C25.5 18.9969 25.5754 18.7949 25.6736 18.6649C25.7715 18.5352 25.8697 18.5 25.9375 18.5H30.0625C30.1303 18.5 30.2285 18.5352 30.3264 18.6649C30.4246 18.7949 30.5 18.9969 30.5 19.2411Z" stroke="#023DFE" stroke-opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,23 @@
<svg width="35" height="36" viewBox="0 0 35 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.66933 30.6933C5.53419 30.6933 5.39898 30.6418 5.29581 30.5386C5.08955 30.3323 5.08955 29.9979 5.29581 29.7917L13.1989 21.8886C13.4052 21.6823 13.7396 21.6823 13.9459 21.8886C14.1521 22.0949 14.1521 22.4293 13.9459 22.6355L6.04286 30.5386C5.93969 30.6418 5.80448 30.6933 5.66933 30.6933Z" fill="#E9EDF1"/>
<path d="M20.7589 15.6035C20.6238 15.6035 20.4886 15.552 20.3854 15.4488C20.1791 15.2425 20.1791 14.9081 20.3854 14.7019L28.9575 6.1298C29.1639 5.92353 29.4982 5.92353 29.7045 6.1298C29.9108 6.33607 29.9108 6.6705 29.7045 6.8767L21.1325 15.4488C21.0293 15.5519 20.8941 15.6035 20.7589 15.6035Z" fill="#E9EDF1"/>
<path d="M29.3309 30.6232C29.1958 30.6232 29.0605 30.5716 28.9574 30.4684L23.4486 24.9597C23.2424 24.7534 23.2424 24.419 23.4486 24.2128C23.655 24.0065 23.9894 24.0065 24.1956 24.2128L29.7043 29.7215C29.9106 29.9278 29.9106 30.2622 29.7043 30.4684C29.6013 30.5716 29.466 30.6232 29.3309 30.6232Z" fill="#E9EDF1"/>
<path d="M11.2132 12.5055C11.0781 12.5055 10.9429 12.4539 10.8397 12.3508L5.33097 6.84203C5.1247 6.63576 5.1247 6.30133 5.33097 6.09513C5.53731 5.88886 5.87167 5.88886 6.07794 6.09513L11.5867 11.6039C11.7929 11.8101 11.7929 12.1446 11.5867 12.3508C11.4835 12.4539 11.3484 12.5055 11.2132 12.5055Z" fill="#E9EDF1"/>
<path d="M29.1335 15.7045H27.1526C27.0645 15.7045 26.9878 15.6461 26.9631 15.5616C26.7624 14.8743 26.4885 14.2186 26.1511 13.6024C26.1089 13.525 26.1216 13.4299 26.1835 13.3672L27.585 11.9658C27.6624 11.8891 27.6624 11.7644 27.585 11.6869L24.1462 8.24822C24.0688 8.17075 23.9441 8.17075 23.8673 8.24822L22.4659 9.64962C22.4033 9.71159 22.3082 9.72427 22.2307 9.68202C21.6145 9.34469 20.9589 9.07075 20.2716 8.87005C20.1871 8.8454 20.1286 8.76864 20.1286 8.68061V6.69962C20.1286 6.59047 20.0406 6.50244 19.9314 6.50244H15.0681C14.9589 6.50244 14.8709 6.59047 14.8709 6.69962V8.68061C14.8709 8.76864 14.8124 8.8454 14.7279 8.87005C14.0406 9.07075 13.385 9.34469 12.7688 9.68202C12.6913 9.72427 12.5962 9.71159 12.5335 9.64962L11.1321 8.24822C11.0554 8.17075 10.9307 8.17075 10.8533 8.24822L7.41454 11.6869C7.33707 11.7644 7.33707 11.8891 7.41454 11.9658L8.81595 13.3672C8.87792 13.4299 8.89059 13.525 8.84834 13.6024C8.5258 14.1919 8.26102 14.8165 8.06313 15.4714C8.05397 15.501 8.06454 15.5651 8.05538 15.5954C8.03073 15.6799 7.95397 15.7384 7.86595 15.7384L6.03214 15.8306C5.92299 15.8306 5.83496 15.9186 5.83496 16.0278L5.86524 20.5644C5.86524 20.6736 5.95327 20.7616 6.06243 20.7616L7.93848 20.7679C8.02651 20.7679 8.10327 20.8264 8.12792 20.9109C8.32862 21.5982 8.71242 22.4461 9.04975 23.0623C9.092 23.1398 9.07933 23.2348 9.01735 23.2975L7.62721 24.7038C7.54975 24.7806 7.54975 24.9052 7.62721 24.9827L10.8575 28.0503C10.935 28.1278 11.0596 28.1278 11.1364 28.0503L12.4399 26.8398C12.5026 26.7778 12.5976 26.7651 12.6751 26.8074C13.2913 27.1447 14.2645 27.4503 14.9519 27.651C15.0364 27.6757 15.0948 27.7524 15.0948 27.8405L15.0413 29.7524C15.0413 29.8616 15.1293 29.9496 15.2385 29.9496L19.7159 29.9081C19.8251 29.9081 19.9131 29.82 19.9131 29.7109L19.9645 27.8764C19.9645 27.7883 20.023 27.7116 20.1075 27.6869C20.5575 27.556 21.1371 27.4771 21.5575 27.2855C21.6258 27.2545 21.7814 27.2158 21.7814 27.2158C21.9335 27.1426 22.0835 27.0658 22.2307 26.9848C22.3082 26.9426 22.4033 26.9552 22.4659 27.0172L23.8673 28.4186C23.9441 28.4961 24.0688 28.4961 24.1462 28.4186L27.585 24.9799C27.6624 24.9024 27.6624 24.7778 27.585 24.701L26.1835 23.2996C26.1216 23.2369 26.1089 23.1419 26.1511 23.0644C26.4885 22.4482 26.7624 21.7926 26.9631 21.1052C26.9878 21.0207 27.0645 20.9623 27.1526 20.9623H29.1335C29.2427 20.9623 29.3307 20.8743 29.3307 20.7651V15.9017C29.3307 15.7926 29.2427 15.7045 29.1335 15.7045ZM17.5399 21.2693C15.8962 21.2693 14.5638 19.9369 14.5638 18.2933C14.5638 16.6496 15.8962 15.3172 17.5399 15.3172C19.1835 15.3172 20.5159 16.6496 20.5159 18.2933C20.5159 19.9369 19.1835 21.2693 17.5399 21.2693Z" fill="#C3C1C9"/>
<path d="M21.7816 27.2158C21.2992 27.4489 20.7943 27.6439 20.2718 27.7967C20.1872 27.8214 20.1288 27.8982 20.1288 27.9862V29.9672C20.1288 30.0763 20.0408 30.1644 19.9316 30.1644H15.0682C14.9591 30.1644 14.8711 30.0763 14.8711 29.9672V27.9862C14.8711 27.8982 14.8126 27.8214 14.7281 27.7967C14.0408 27.596 13.3851 27.3221 12.7689 26.9848C12.6915 26.9425 12.5964 26.9552 12.5337 27.0172L11.1323 28.4186C11.0556 28.496 10.9309 28.496 10.8534 28.4186L7.41472 24.9798C7.33725 24.9024 7.33725 24.7777 7.41472 24.701L8.81613 23.2996C8.8781 23.2369 8.89078 23.1418 8.84852 23.0644C8.5112 22.4482 8.23725 21.7925 8.03655 21.1052C8.0119 21.0207 7.93514 20.9622 7.84711 20.9622H5.86613C5.75697 20.9622 5.66895 20.8742 5.66895 20.7651V15.9017C5.66895 15.7925 5.75697 15.7045 5.86613 15.7045H7.84711C7.93514 15.7045 8.0119 15.6461 8.03655 15.5615C8.045 15.5313 8.05352 15.5008 8.06338 15.4712C8.12747 22.0367 13.4704 27.3397 20.0513 27.3397C20.6387 27.3397 21.2168 27.2975 21.7816 27.2158Z" fill="#ADACB5"/>
<path d="M17.5401 12.272C14.2148 12.272 11.5183 14.9677 11.5183 18.2938C11.5183 21.6192 14.2148 24.3156 17.5401 24.3156C20.8662 24.3156 23.562 21.6192 23.562 18.2938C23.562 14.9677 20.8662 12.272 17.5401 12.272ZM17.5401 20.653C16.2373 20.653 15.181 19.5966 15.181 18.2938C15.181 16.991 16.2373 15.9346 17.5401 15.9346C18.843 15.9346 19.8993 16.991 19.8993 18.2938C19.8993 19.5966 18.843 20.653 17.5401 20.653Z" fill="#ADACB5"/>
<path d="M34.9999 4.53117C34.9999 2.48926 33.3446 0.833984 31.3027 0.833984C30.589 0.833984 29.9225 1.03624 29.3574 1.38652C29.3574 1.38652 29.164 1.54589 29.0626 1.62441C28.1892 2.30067 27.7471 3.3411 27.7471 4.53124C27.7471 6.57314 29.2607 8.01637 31.3026 8.01637C32.404 8.01637 33.3538 7.71511 34.0312 6.95102C34.114 6.85757 34.3045 6.68997 34.3045 6.68997C34.7421 6.0825 34.9999 5.33694 34.9999 4.53117Z" fill="#73C2FB"/>
<path d="M34.3045 6.69058C33.6334 7.62227 32.5386 8.22903 31.3026 8.22903C29.2611 8.22903 27.6055 6.5734 27.6055 4.53185C27.6055 3.20368 28.306 2.03862 29.3574 1.38721C28.9193 1.99425 28.6618 2.7403 28.6618 3.54594C28.6618 5.58749 30.3174 7.24312 32.359 7.24312C33.0731 7.24312 33.7397 7.04129 34.3045 6.69058Z" fill="#4B9CD3"/>
<path d="M31.3028 6.11652C32.1779 6.11652 32.8873 5.40711 32.8873 4.53202C32.8873 3.65692 32.1779 2.94751 31.3028 2.94751C30.4277 2.94751 29.7183 3.65692 29.7183 4.53202C29.7183 5.40711 30.4277 6.11652 31.3028 6.11652Z" fill="#4B9CD3"/>
<path d="M7.39434 4.53117C7.39434 2.48926 5.73906 0.833984 3.69716 0.833984C2.98343 0.833984 2.31695 1.03624 1.75188 1.38652C1.75188 1.38652 1.55843 1.54589 1.45709 1.62441C0.583714 2.3006 0.141602 3.3411 0.141602 4.53117C0.141602 6.57307 1.65526 8.0163 3.69716 8.0163C4.79857 8.0163 5.74836 7.71504 6.42568 6.95095C6.50857 6.8575 6.69899 6.6899 6.69899 6.6899C7.1366 6.0825 7.39434 5.33694 7.39434 4.53117Z" fill="#7CB9E8"/>
<path d="M6.69901 6.69058C6.02788 7.62227 4.9331 8.22903 3.69718 8.22903C1.65563 8.22903 0 6.5734 0 4.53185C0 3.20368 0.700493 2.03862 1.7519 1.38721C1.31387 1.99425 1.05634 2.7403 1.05634 3.54594C1.05634 5.58749 2.71197 7.24312 4.75352 7.24312C5.4676 7.24312 6.13422 7.04129 6.69901 6.69058Z" fill="#6699CC"/>
<path d="M3.69705 6.11652C4.57215 6.11652 5.28156 5.40711 5.28156 4.53202C5.28156 3.65692 4.57215 2.94751 3.69705 2.94751C2.82196 2.94751 2.11255 3.65692 2.11255 4.53202C2.11255 5.40711 2.82196 6.11652 3.69705 6.11652Z" fill="#6699CC"/>
<path d="M35.0001 32.1376C35.0001 30.0957 33.3448 28.4404 31.3029 28.4404C30.5892 28.4404 29.9227 28.6427 29.3577 28.993C29.3577 28.993 29.1642 29.1523 29.0629 29.2309C28.1894 29.9071 27.7473 30.9475 27.7473 32.1377C27.7473 34.1796 29.261 35.6228 31.3029 35.6228C32.4043 35.6228 33.3541 35.3216 34.0314 34.5575C34.1143 34.464 34.3047 34.2964 34.3047 34.2964C34.7424 33.6889 35.0001 32.9434 35.0001 32.1376Z" fill="#6086FF"/>
<path d="M34.305 34.2956C33.6338 35.2273 32.5391 35.834 31.3031 35.834C29.2616 35.834 27.606 34.1784 27.606 32.1368C27.606 30.8087 28.3065 29.6436 29.3579 28.9922C28.9198 29.5992 28.6623 30.3453 28.6623 31.1509C28.6623 33.1925 30.3179 34.8481 32.3595 34.8481C33.0736 34.8481 33.7402 34.6463 34.305 34.2956Z" fill="#023DFE"/>
<path d="M31.3033 33.7217C32.1784 33.7217 32.8878 33.0123 32.8878 32.1372C32.8878 31.2621 32.1784 30.5527 31.3033 30.5527C30.4282 30.5527 29.7188 31.2621 29.7188 32.1372C29.7188 33.0123 30.4282 33.7217 31.3033 33.7217Z" fill="#023DFE"/>
<path d="M7.39434 32.1376C7.39434 30.0957 5.73906 28.4404 3.69716 28.4404C2.98343 28.4404 2.31695 28.6427 1.75188 28.993C1.75188 28.993 1.55843 29.1523 1.45709 29.2309C0.583714 29.907 0.141602 30.9475 0.141602 32.1376C0.141602 34.1795 1.65526 35.6228 3.69716 35.6228C4.79857 35.6228 5.74836 35.3215 6.42568 34.5574C6.50857 34.4639 6.69899 34.2963 6.69899 34.2963C7.1366 33.6889 7.39434 32.9434 7.39434 32.1376Z" fill="#76ABDF"/>
<path d="M6.69901 34.2956C6.02788 35.2273 4.9331 35.834 3.69718 35.834C1.65563 35.834 0 34.1784 0 32.1368C0 30.8087 0.700493 29.6436 1.7519 28.9922C1.31387 29.5992 1.05634 30.3453 1.05634 31.1509C1.05634 33.1925 2.71197 34.8481 4.75352 34.8481C5.4676 34.8481 6.13422 34.6463 6.69901 34.2956Z" fill="#4682B4"/>
<path d="M3.69705 33.7217C4.57215 33.7217 5.28156 33.0123 5.28156 32.1372C5.28156 31.2621 4.57215 30.5527 3.69705 30.5527C2.82196 30.5527 2.11255 31.2621 2.11255 32.1372C2.11255 33.0123 2.82196 33.7217 3.69705 33.7217Z" fill="#4682B4"/>
<path d="M11.5185 18.8222C11.6454 18.8222 11.7693 18.7765 11.8664 18.6915L13.8114 16.9891C14.0309 16.797 14.0532 16.4634 13.861 16.2439C13.669 16.0243 13.3352 16.0022 13.1157 16.1943L12.2055 16.9909C12.7957 14.5928 14.9731 12.8005 17.54 12.8005C19.8371 12.8005 21.9109 14.2491 22.7002 16.4051C22.8006 16.6791 23.1037 16.8198 23.3778 16.7195C23.6517 16.6192 23.7925 16.3158 23.6922 16.0419C22.751 13.4713 20.2786 11.7441 17.54 11.7441C15.8053 11.7441 14.1704 12.4155 12.9366 13.6347C12.1095 14.452 11.5277 15.4527 11.2267 16.5455L10.8242 15.7489C10.6926 15.4885 10.3748 15.384 10.1146 15.5156C9.85425 15.6472 9.74974 15.9648 9.88136 16.2252L11.0471 18.5322C11.1207 18.6779 11.2575 18.7814 11.4178 18.8125C11.4513 18.819 11.485 18.8222 11.5185 18.8222Z" fill="#F7F9FA"/>
<path d="M25.1992 20.368L24.0335 18.061C23.9598 17.9153 23.823 17.8118 23.6627 17.7807C23.5027 17.7496 23.337 17.7942 23.2142 17.9018L21.2691 19.6042C21.0496 19.7963 21.0273 20.1299 21.2195 20.3494C21.4116 20.5689 21.7452 20.5911 21.9648 20.399L22.8727 19.6044C22.2802 21.999 20.1049 23.7877 17.5399 23.7877C15.2331 23.7877 13.1564 22.3309 12.3722 20.1627C12.273 19.8883 11.9701 19.7463 11.6959 19.8456C11.4215 19.9449 11.2796 20.2476 11.3788 20.522C12.3137 23.1071 14.7897 24.844 17.5399 24.844C19.2753 24.844 20.9105 24.1721 22.1446 22.9522C22.9704 22.1357 23.5515 21.1364 23.8524 20.0451L24.2563 20.8444C24.3492 21.0284 24.5351 21.1345 24.7281 21.1345C24.8082 21.1345 24.8895 21.1162 24.9659 21.0776C25.2263 20.9461 25.3308 20.6284 25.1992 20.368Z" fill="#F7F9FA"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,148 @@
<svg width="290" height="290" viewBox="0 0 290 290" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_4111_484)">
<rect x="20" y="20" width="250" height="250" rx="100" fill="#EDEDED"/>
<path d="M92.5676 124.459H197.432V204.459H92.5676V124.459Z" fill="url(#paint0_linear_4111_484)"/>
<path d="M92.5908 149.353H130.176V205H92.5908V149.353Z" fill="url(#paint1_linear_4111_484)"/>
<g clip-path="url(#clip0_4111_484)">
<path d="M92.5908 145.541H197.409V177.658H92.5908V145.541Z" fill="url(#paint2_linear_4111_484)"/>
<path d="M92.7646 122.838H197.471V135.308H92.7646V122.838Z" fill="url(#paint3_linear_4111_484)"/>
<path d="M92.7646 132.72H197.471V145.191H92.7646V132.72Z" fill="url(#paint4_linear_4111_484)"/>
<path d="M92.7646 142.838H197.471V155.308H92.7646V142.838Z" fill="url(#paint5_linear_4111_484)"/>
<path d="M92.7646 152.568H197.471V165.038H92.7646V152.568Z" fill="url(#paint6_linear_4111_484)"/>
<path d="M92.7646 162.45H197.471V174.921H92.7646V162.45Z" fill="url(#paint7_linear_4111_484)"/>
<path d="M92.7646 172.568H197.471V185.038H92.7646V172.568Z" fill="url(#paint8_linear_4111_484)"/>
<path d="M92.7646 182.45H197.471V194.921H92.7646V182.45Z" fill="url(#paint9_linear_4111_484)"/>
<path d="M92.7646 192.332H197.471V204.803H92.7646V192.332Z" fill="url(#paint10_linear_4111_484)"/>
</g>
<path d="M199.649 114.801L156.765 88.0353C153.522 86.0118 149.261 85 145 85C140.739 85 136.478 86.0118 133.235 88.0353L90.3513 114.801C87.0226 116.879 85 120.525 85 124.449V197.537C85 201.659 88.3412 205 92.4628 205C94.58 205 96.2965 203.284 96.2965 201.166V134.999C96.2965 130.646 99.8252 127.118 104.178 127.118H185.822C190.175 127.118 193.704 130.646 193.704 134.999V201.166C193.704 203.284 195.42 205 197.537 205C201.659 205 205 201.659 205 197.537V124.449C205 120.525 202.977 116.879 199.649 114.801Z" fill="url(#paint11_linear_4111_484)"/>
<path d="M199.649 114.801L156.765 88.0353C153.522 86.0118 149.261 85 145 85C140.739 85 136.478 86.0118 133.235 88.0353L90.3513 114.801C87.0226 116.879 85 120.525 85 124.449V135.743C85 131.819 87.0226 128.172 90.3513 126.095L133.235 99.3287C136.478 97.3052 140.739 96.2934 145 96.2934C149.261 96.2934 153.522 97.3052 156.765 99.3287L199.649 126.095C202.977 128.172 205 131.819 205 135.743V124.449C205 120.525 202.977 116.879 199.649 114.801Z" fill="url(#paint12_linear_4111_484)"/>
<path d="M131.593 111.677H158.407C159.926 111.677 161.156 110.446 161.156 108.928C161.156 107.41 159.926 106.179 158.407 106.179H131.593C130.074 106.179 128.844 107.41 128.844 108.928C128.844 110.446 130.075 111.677 131.593 111.677Z" fill="url(#paint13_linear_4111_484)"/>
<path d="M131.593 121.795H158.407C159.926 121.795 161.156 120.564 161.156 119.046C161.156 117.527 159.926 116.297 158.407 116.297H131.593C130.074 116.297 128.844 117.528 128.844 119.046C128.844 120.564 130.075 121.795 131.593 121.795Z" fill="url(#paint14_linear_4111_484)"/>
<path d="M205 135.744V197.536C205 199.598 204.165 201.464 202.814 202.814C201.464 204.165 199.598 205 197.536 205C195.419 205 193.704 203.285 193.704 201.167V134.998C193.704 130.647 190.174 127.118 185.821 127.118H104.179C99.8259 127.118 96.2965 130.647 96.2965 134.998V201.167C96.2965 202.226 95.8682 203.184 95.1741 203.878C94.48 204.572 93.5224 205 92.4635 205C88.3412 205 85 201.659 85 197.536V135.744C85 131.819 87.0235 128.172 90.3506 126.094L133.235 99.3294C136.478 97.3059 140.739 96.2941 145 96.2941C149.261 96.2941 153.522 97.3059 156.765 99.3294L199.649 126.094C202.976 128.172 205 131.819 205 135.744Z" fill="url(#paint15_linear_4111_484)"/>
<path d="M145.236 89.7092C138.367 89.7092 131.708 91.6861 125.979 95.4266C124.456 96.4207 124.028 98.4609 125.022 99.9835L130.442 105.42C130.241 106.14 130.336 106.937 130.775 107.613L135.816 112.723C135.627 113.301 135.689 113.956 136.044 114.508L141.425 119.781C141.068 121.102 141.404 122.572 142.442 123.61L145.949 127.118H185.822C190.175 127.118 193.704 130.646 193.704 134.999V174.872L205 186.168V135.955L164.492 95.4266C158.763 91.6864 152.104 89.7092 145.236 89.7092Z" fill="url(#paint16_linear_4111_484)"/>
<path d="M153.562 111.378C151.008 109.737 148.047 108.87 145 108.87C141.953 108.87 138.992 109.737 136.438 111.377C135.465 112.003 135.183 113.299 135.808 114.273C136.433 115.246 137.73 115.528 138.703 114.903C140.58 113.697 142.757 113.06 145 113.06C147.243 113.06 149.42 113.697 151.297 114.903C151.647 115.128 152.039 115.236 152.427 115.236C153.117 115.236 153.792 114.896 154.192 114.273C154.817 113.3 154.535 112.003 153.562 111.378Z" fill="url(#paint17_linear_4111_484)"/>
<path d="M158.669 103.651C154.599 101.007 149.872 99.6099 145 99.6099C140.128 99.6099 135.401 101.007 131.331 103.651C130.083 104.461 129.729 106.13 130.539 107.377C131.35 108.625 133.018 108.98 134.266 108.169C137.46 106.094 141.172 104.998 145 104.998C148.828 104.998 152.54 106.094 155.734 108.169C156.187 108.464 156.696 108.604 157.199 108.604C158.08 108.604 158.944 108.172 159.46 107.377C160.271 106.13 159.917 104.461 158.669 103.651Z" fill="url(#paint18_linear_4111_484)"/>
<path d="M164.256 95.1913C158.528 91.4508 151.869 89.4736 145 89.4736C138.131 89.4736 131.472 91.4506 125.744 95.1911C124.221 96.1852 123.792 98.2254 124.787 99.748C125.781 101.271 127.821 101.699 129.344 100.705C133.999 97.6654 139.413 96.0588 145 96.0588C150.587 96.0588 156.001 97.6654 160.656 100.705C161.212 101.068 161.836 101.241 162.453 101.241C163.528 101.241 164.582 100.716 165.213 99.7482C166.208 98.2256 165.779 96.1854 164.256 95.1913Z" fill="url(#paint19_linear_4111_484)"/>
<path d="M145 124.532C147.182 124.532 148.951 122.763 148.951 120.581C148.951 118.399 147.182 116.63 145 116.63C142.818 116.63 141.049 118.399 141.049 120.581C141.049 122.763 142.818 124.532 145 124.532Z" fill="url(#paint20_linear_4111_484)"/>
</g>
<defs>
<filter id="filter0_d_4111_484" x="0" y="0" width="290" height="290" 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="10"/>
<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.35 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4111_484"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4111_484" result="shape"/>
</filter>
<linearGradient id="paint0_linear_4111_484" x1="145" y1="154.648" x2="145" y2="196.939" gradientUnits="userSpaceOnUse">
<stop stop-color="#62DBFB"/>
<stop offset="0.1912" stop-color="#57D5FA"/>
<stop offset="0.5232" stop-color="#3BC5F7"/>
<stop offset="0.954" stop-color="#0DABF2"/>
<stop offset="1" stop-color="#08A9F1"/>
</linearGradient>
<linearGradient id="paint1_linear_4111_484" x1="105.706" y1="177.176" x2="93.7059" y2="177.176" gradientUnits="userSpaceOnUse">
<stop stop-color="#0593FC" stop-opacity="0"/>
<stop offset="0.6831" stop-color="#0389FC" stop-opacity="0.683"/>
<stop offset="1" stop-color="#0182FC"/>
</linearGradient>
<linearGradient id="paint2_linear_4111_484" x1="145" y1="164.717" x2="145" y2="148.715" gradientUnits="userSpaceOnUse">
<stop stop-color="#0593FC" stop-opacity="0"/>
<stop offset="0.6831" stop-color="#0389FC" stop-opacity="0.683"/>
<stop offset="1" stop-color="#0182FC"/>
</linearGradient>
<linearGradient id="paint3_linear_4111_484" x1="145.118" y1="127.544" x2="145.118" y2="134.136" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint4_linear_4111_484" x1="145.118" y1="137.426" x2="145.118" y2="144.019" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint5_linear_4111_484" x1="145.118" y1="147.544" x2="145.118" y2="154.136" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint6_linear_4111_484" x1="145.118" y1="157.273" x2="145.118" y2="163.866" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint7_linear_4111_484" x1="145.118" y1="167.156" x2="145.118" y2="173.748" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint8_linear_4111_484" x1="145.118" y1="177.273" x2="145.118" y2="183.866" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint9_linear_4111_484" x1="145.118" y1="187.156" x2="145.118" y2="193.748" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint10_linear_4111_484" x1="145.118" y1="197.038" x2="145.118" y2="203.631" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint11_linear_4111_484" x1="112.144" y1="101.95" x2="168.144" y2="201.715" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint12_linear_4111_484" x1="145" y1="67.5915" x2="145" y2="137.895" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint13_linear_4111_484" x1="145" y1="110.944" x2="145" y2="105.881" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint14_linear_4111_484" x1="145" y1="121.061" x2="145" y2="115.998" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint15_linear_4111_484" x1="126.473" y1="129.525" x2="115.65" y2="108.113" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint16_linear_4111_484" x1="175.367" y1="132.235" x2="141.72" y2="85.8824" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint17_linear_4111_484" x1="143.315" y1="108.32" x2="146.188" y2="116.541" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint18_linear_4111_484" x1="142.584" y1="97.1318" x2="145.857" y2="109.025" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint19_linear_4111_484" x1="142.471" y1="88.6965" x2="145.983" y2="101.547" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint20_linear_4111_484" x1="141.169" y1="116.749" x2="147.514" y2="123.095" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<clipPath id="clip0_4111_484">
<rect width="104.88" height="81.9651" fill="white" transform="translate(92.5908 122.838)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,32 @@
<svg width="33" height="319" viewBox="0 0 33 319" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32.675 6.07198V318.219L30.535 319V5.29102L32.675 6.07198Z" fill="url(#paint0_linear_4847_2158)"/>
<path d="M0.525162 315.619L30.5352 319V5.29102L0.525162 8.68132V315.619Z" fill="url(#paint1_linear_4847_2158)"/>
<path d="M17.9751 0.0722656H13.0851V7.5144C13.0851 8.50669 13.9651 9.31522 15.0451 9.31522H16.0151C17.0951 9.31522 17.9751 8.50669 17.9751 7.5144V0.0722656Z" fill="url(#paint2_linear_4847_2158)"/>
<defs>
<linearGradient id="paint0_linear_4847_2158" x1="82.145" y1="20.5612" x2="-9.30122" y2="323.172" gradientUnits="userSpaceOnUse">
<stop stop-color="#E9E9E9"/>
<stop offset="0.26" stop-color="#E4E4E4"/>
<stop offset="0.51" stop-color="#D8D8D8"/>
<stop offset="0.77" stop-color="#C4C4C4"/>
<stop offset="0.78" stop-color="#C4C4C4"/>
<stop offset="1" stop-color="#C6C6C6"/>
</linearGradient>
<linearGradient id="paint1_linear_4847_2158" x1="30.5352" y1="-18.0001" x2="0.525162" y2="-18.0001" gradientUnits="userSpaceOnUse">
<stop stop-color="#F5F5F5"/>
<stop offset="0.22" stop-color="#F0F0F0"/>
<stop offset="0.45" stop-color="#E4E4E4"/>
<stop offset="0.67" stop-color="#D0D0D0"/>
<stop offset="0.78" stop-color="#C4C4C4"/>
<stop offset="1" stop-color="#C6C6C6"/>
</linearGradient>
<linearGradient id="paint2_linear_4847_2158" x1="17.9751" y1="-18.0002" x2="13.0851" y2="-18.0002" gradientUnits="userSpaceOnUse">
<stop stop-color="#C4C4C4"/>
<stop offset="0.41" stop-color="#F8F8F8"/>
<stop offset="0.49" stop-color="#F0F0F0"/>
<stop offset="0.6" stop-color="#DCDCDC"/>
<stop offset="0.75" stop-color="#BABABA"/>
<stop offset="0.79" stop-color="#AEAEAE"/>
<stop offset="1" stop-color="#BEBEBE"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,25 @@
<svg width="23" height="18" viewBox="0 0 23 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.3032 0.832703H1.4526C1.10932 0.832703 0.830078 1.11285 0.830078 1.45725V16.6318C0.830078 16.9762 1.10932 17.2563 1.4526 17.2563H22.3032C22.6463 17.2563 22.9257 16.9762 22.9257 16.6318V1.45725C22.9257 1.11265 22.6465 0.832703 22.3032 0.832703Z" fill="#E6E7E8"/>
<path d="M21.8881 0.624556V15.7989C21.8881 16.029 21.7023 16.2153 21.4731 16.2153H0.622537C0.393143 16.2153 0.20752 16.029 0.20752 15.7989V0.624556C0.20752 0.394417 0.393143 0.208191 0.622537 0.208191H21.4731C21.7023 0.208191 21.8881 0.394417 21.8881 0.624556Z" fill="white"/>
<path d="M0.20752 15.7989C0.20752 16.0288 0.393143 16.2152 0.622537 16.2152H21.4731C21.7023 16.2152 21.8881 16.0288 21.8881 15.7989V0.832703H0.20752V15.7989Z" fill="#D4FBFF"/>
<path d="M4.44421 8.45071C4.36336 8.45071 4.29 8.3952 4.27055 8.31266C3.4626 4.87562 2.7657 4.37773 2.4283 4.37427C1.65825 4.38423 0.871172 6.79256 0.555856 8.30819C0.535592 8.40517 0.440754 8.46758 0.3447 8.44705C0.248038 8.42672 0.186231 8.33177 0.206293 8.235C0.29566 7.80501 1.11779 4.03293 2.42364 4.01605H2.43336C3.2484 4.01605 3.94267 5.35582 4.61829 8.23053C4.64098 8.32669 4.58161 8.42326 4.48555 8.44603C4.47157 8.44928 4.45799 8.45071 4.44421 8.45071Z" fill="#FFD7E5"/>
<path d="M12.6696 8.59971C12.5887 8.59971 12.5156 8.54421 12.4959 8.46167C11.6916 5.03987 11.001 4.52328 10.6583 4.52328C10.6569 4.52328 10.6553 4.52348 10.6539 4.52348C9.88383 4.53344 9.09696 6.94157 8.78164 8.45719C8.76118 8.55417 8.66634 8.61679 8.57029 8.59605C8.47362 8.57572 8.41182 8.48078 8.43188 8.38401C8.52145 7.95402 9.34358 4.18193 10.6494 4.16526C11.4762 4.15693 12.1656 5.49364 12.8437 8.37953C12.8664 8.4757 12.807 8.57226 12.7109 8.59524C12.6972 8.59829 12.6834 8.59971 12.6696 8.59971Z" fill="#FFD7E5"/>
<path d="M20.7961 8.29596C20.7152 8.29596 20.6418 8.24046 20.6224 8.15792C19.8181 4.73612 19.1275 4.21953 18.7848 4.21953C18.7832 4.21953 18.7818 4.21973 18.7803 4.21973C18.0103 4.2297 17.2234 6.63782 16.9081 8.15345C16.8878 8.25042 16.7928 8.31284 16.6968 8.2923C16.6001 8.27197 16.5383 8.17703 16.5583 8.08026C16.6477 7.65027 17.47 3.87818 18.7759 3.86151C19.5903 3.84647 20.2921 5.1899 20.9701 8.07579C20.9928 8.17195 20.9335 8.26852 20.8374 8.29149C20.8234 8.29454 20.8098 8.29596 20.7961 8.29596Z" fill="#FFD7E5"/>
<path d="M6.52174 12.5619C6.5185 12.5619 6.51546 12.5617 6.51181 12.5617C5.17537 12.5448 4.33378 8.7729 4.24219 8.34291C4.22152 8.24594 4.28495 8.15099 4.38384 8.13087C4.48252 8.11074 4.57959 8.17275 4.60006 8.26972C4.92287 9.78535 5.729 12.1935 6.51668 12.2034C6.5181 12.2034 6.51972 12.2036 6.52114 12.2036C6.87212 12.2036 7.57915 11.6875 8.40229 8.26525C8.42519 8.16909 8.52388 8.10993 8.62216 8.13188C8.72065 8.15465 8.78144 8.25122 8.75814 8.34759C8.06671 11.2215 7.35583 12.5619 6.52174 12.5619Z" fill="#FFD7E5"/>
<path d="M14.7221 12.5619C14.7187 12.5619 14.7157 12.5617 14.7124 12.5617C13.4066 12.5448 12.5842 8.7729 12.4949 8.34291C12.4748 8.24594 12.5366 8.15099 12.6333 8.13087C12.7299 8.11074 12.8244 8.17275 12.8446 8.26972C13.1599 9.78535 13.9472 12.1935 14.7169 12.2034C14.7183 12.2034 14.7197 12.2036 14.7213 12.2036C15.064 12.2036 15.7546 11.6875 16.5589 8.26525C16.5816 8.16909 16.6777 8.10972 16.7737 8.13188C16.8698 8.15465 16.9292 8.25122 16.9065 8.34759C16.2314 11.2215 15.5368 12.5619 14.7221 12.5619Z" fill="#FFD7E5"/>
<path d="M21.7088 11.1408C21.6411 11.1408 21.5763 11.102 21.5463 11.0361C20.9983 9.83621 20.6678 8.26468 20.6542 8.1982C20.634 8.10142 20.696 8.00648 20.7926 7.98615C20.8887 7.96602 20.9837 8.02803 21.0038 8.12501C21.0072 8.14087 21.34 9.72419 21.8711 10.8871C21.912 10.9769 21.8727 11.0831 21.783 11.1245C21.7591 11.1357 21.7339 11.1408 21.7088 11.1408Z" fill="#FFD7E5"/>
<path d="M3.03701 8.32623C2.97175 8.32623 2.91238 8.2811 2.89677 8.21462C2.36037 5.93295 1.90949 5.68532 1.73582 5.69386C1.28088 5.69976 0.771229 7.16923 0.554601 8.21096C0.538389 8.28923 0.46179 8.33945 0.383771 8.32298C0.305753 8.30671 0.255902 8.23007 0.271911 8.152C0.366952 7.69498 0.884102 5.41534 1.73177 5.40436H1.73845C2.28033 5.40436 2.7379 6.27653 3.17764 8.14814C3.19588 8.2258 3.14785 8.30387 3.07024 8.32237C3.0593 8.32461 3.04815 8.32623 3.03701 8.32623Z" fill="#FA759E"/>
<path d="M8.34895 8.42239C8.2835 8.42239 8.22412 8.37746 8.20852 8.31078C7.67475 6.03927 7.22204 5.79002 7.04979 5.79002C7.04898 5.79002 7.04838 5.79002 7.04757 5.79002C6.59283 5.79592 6.08318 7.26539 5.86655 8.30712C5.85014 8.38539 5.77333 8.43561 5.69572 8.41914C5.6177 8.40288 5.56765 8.32623 5.58386 8.24816C5.6789 7.79114 6.19605 5.5115 7.04372 5.50052H7.0502C7.59207 5.50052 8.04965 6.37269 8.48939 8.2443C8.50762 8.32196 8.4596 8.40003 8.38198 8.41853C8.37084 8.42117 8.3599 8.42239 8.34895 8.42239Z" fill="#FA759E"/>
<path d="M13.5964 8.22601C13.5309 8.22601 13.4716 8.18108 13.456 8.1144C12.9198 5.83293 12.4648 5.59039 12.295 5.59385C11.8401 5.59974 11.3304 7.06922 11.1138 8.11094C11.0976 8.18921 11.021 8.23984 10.9432 8.22296C10.8651 8.2067 10.8151 8.12985 10.8313 8.05178C10.9263 7.59476 11.4435 5.31532 12.2912 5.30414H12.2976C12.8395 5.30414 13.2971 6.17651 13.7368 8.04812C13.7551 8.12578 13.707 8.20385 13.6294 8.22235C13.6185 8.22479 13.6073 8.22601 13.5964 8.22601Z" fill="#FA759E"/>
<path d="M18.895 8.42239C18.8298 8.42239 18.7704 8.37746 18.7548 8.31078C18.2186 6.02931 17.7635 5.78677 17.5938 5.79002C17.1389 5.79612 16.6292 7.26539 16.4126 8.30712C16.3962 8.38539 16.3198 8.43601 16.242 8.41914C16.1638 8.40288 16.1139 8.32623 16.1301 8.24816C16.2252 7.79114 16.7421 5.5115 17.5898 5.50052H17.5965C18.1383 5.50052 18.5959 6.37269 19.0357 8.2443C19.0539 8.32196 19.0059 8.40003 18.9283 8.41853C18.9171 8.42117 18.9062 8.42239 18.895 8.42239Z" fill="#FA759E"/>
<path d="M4.4265 11.1188C4.42427 11.1188 4.42204 11.1188 4.41981 11.1188C3.57195 11.1076 3.055 8.8282 2.95996 8.37118C2.94375 8.2929 2.9938 8.21626 3.07162 8.19999C3.14984 8.18332 3.22623 8.23374 3.24245 8.31201C3.45928 9.35354 3.96913 10.8234 4.42367 10.8291H4.42589C4.59814 10.8291 5.05065 10.5799 5.58462 8.30856C5.60286 8.2309 5.68067 8.18312 5.75808 8.20081C5.8357 8.2191 5.88352 8.29717 5.86528 8.37504C5.42575 10.2464 4.96838 11.1188 4.4265 11.1188Z" fill="#FA759E"/>
<path d="M9.67406 10.9584C9.67183 10.9584 9.6696 10.9584 9.66737 10.9584C8.81951 10.9474 8.30256 8.66778 8.20752 8.21076C8.19131 8.13248 8.24136 8.05584 8.31917 8.03978C8.3976 8.02311 8.47359 8.07353 8.49 8.1518C8.70683 9.19332 9.21669 10.663 9.67122 10.6689H9.67345C9.8457 10.6689 10.2982 10.4196 10.8322 8.14814C10.8504 8.07027 10.928 8.0229 11.0056 8.04059C11.0833 8.05889 11.1311 8.13696 11.1128 8.21482C10.6733 10.086 10.2159 10.9584 9.67406 10.9584Z" fill="#FA759E"/>
<path d="M14.9774 10.9842C14.9752 10.9842 14.9732 10.9842 14.971 10.9842C14.1229 10.9732 13.6061 8.69361 13.5111 8.23658C13.4949 8.15831 13.5449 8.08166 13.6228 8.0656C13.701 8.04893 13.7772 8.09915 13.7934 8.17762C14.0102 9.21915 14.5201 10.6888 14.9746 10.6947H14.9768C15.1491 10.6947 15.6016 10.4455 16.1356 8.17396C16.1538 8.0963 16.2316 8.04873 16.309 8.06642C16.3866 8.08471 16.4347 8.16278 16.4164 8.24065C15.9767 10.1121 15.5193 10.9842 14.9774 10.9842Z" fill="#FA759E"/>
<path d="M20.234 11.1188C20.2318 11.1188 20.2298 11.1188 20.2274 11.1188C19.3795 11.1076 18.8627 8.8282 18.7677 8.37118C18.7515 8.2929 18.8015 8.21626 18.8794 8.19999C18.9576 8.18332 19.0338 8.23374 19.05 8.31201C19.2668 9.35354 19.7767 10.8234 20.2312 10.8291H20.2334C20.4057 10.8291 20.8582 10.5799 21.3922 8.30856C21.4104 8.2309 21.4882 8.18312 21.5656 8.20081C21.6432 8.2191 21.6913 8.29717 21.673 8.37504C21.2335 10.2464 20.7759 11.1188 20.234 11.1188Z" fill="#FA759E"/>
<path d="M5.67451 8.26302C5.58717 8.26302 5.50794 8.20284 5.48707 8.11399C4.43696 3.6462 3.52019 2.97225 3.06363 2.97225C3.06161 2.97225 3.05958 2.97225 3.05776 2.97225C2.03541 2.98567 1.00151 6.12996 0.589942 8.10912C0.568258 8.21382 0.46572 8.28091 0.361763 8.25895C0.257401 8.2372 0.190528 8.13473 0.212211 8.02983C0.327719 7.47501 1.38816 2.60651 3.05269 2.58496H3.06404C4.08719 2.58496 5.00254 4.36447 5.86257 8.02495C5.88709 8.12884 5.82265 8.23333 5.7191 8.25793C5.7043 8.26139 5.68931 8.26302 5.67451 8.26302Z" fill="#0089EF"/>
<path d="M16.3507 8.26302C16.2633 8.26302 16.1841 8.20284 16.163 8.11399C15.1131 3.6462 14.1964 2.97225 13.7398 2.97225C13.7378 2.97225 13.7357 2.97225 13.7337 2.97225C12.7116 2.98567 11.6779 6.12996 11.2661 8.10912C11.2442 8.21382 11.1419 8.28091 11.0379 8.25895C10.9336 8.2372 10.8667 8.13473 10.8882 8.02983C11.0039 7.47501 12.0641 2.60651 13.7286 2.58496H13.74C14.7627 2.58496 15.6781 4.36447 16.5385 8.02495C16.563 8.12884 16.4986 8.23333 16.3951 8.25793C16.3805 8.26139 16.3655 8.26302 16.3507 8.26302Z" fill="#0089EF"/>
<path d="M8.46634 13.838C8.46269 13.838 8.45884 13.838 8.45499 13.838C6.79046 13.8164 5.73002 8.94794 5.61431 8.39292C5.59263 8.28843 5.6595 8.18576 5.76406 8.164C5.86802 8.14205 5.97056 8.20934 5.99224 8.31384C6.40422 10.2928 7.43832 13.4375 8.45985 13.4505H8.46593C8.9227 13.4505 9.83926 12.777 10.8892 8.30896C10.9137 8.20507 11.0178 8.14123 11.1212 8.16482C11.2249 8.18942 11.2892 8.29371 11.2647 8.3978C10.4046 12.0583 9.48909 13.838 8.46634 13.838Z" fill="#0089EF"/>
<path d="M19.014 13.6947C19.0103 13.6947 19.0065 13.6947 19.0026 13.6947C17.3381 13.6729 16.2776 8.80464 16.1619 8.24963C16.1402 8.14513 16.2069 8.04246 16.3117 8.0205C16.416 7.99875 16.518 8.06604 16.5399 8.17054C16.9518 10.1495 17.9859 13.294 19.0075 13.3072H19.0135C19.4703 13.3072 20.3869 12.6335 21.4368 8.16546C21.4613 8.06157 21.5655 7.99794 21.6688 8.02152C21.7726 8.04592 21.837 8.15021 21.8123 8.2543C20.9523 11.9148 20.0367 13.6947 19.014 13.6947Z" fill="#0089EF"/>
<path d="M21.4731 0H0.622526C0.279245 0 0 0.280152 0 0.624547V15.7991C0 16.1435 0.279245 16.4236 0.622526 16.4236H21.4731C21.8162 16.4236 22.0956 16.1435 22.0956 15.7991V6.08324C22.0956 5.96817 22.0026 5.87506 21.8881 5.87506C21.7734 5.87506 21.6806 5.96817 21.6806 6.08324V8.00323H18.0263C17.7882 6.70921 16.7602 1.48066 15.5275 0.416365H21.4731C21.5874 0.416365 21.6806 0.509681 21.6806 0.624547V2.90866C21.6806 3.02373 21.7734 3.11684 21.8881 3.11684C22.0026 3.11684 22.0956 3.02373 22.0956 2.90866V0.624547C22.0956 0.279949 21.8164 0 21.4731 0ZM17.6453 8.4196C17.94 9.69594 19.2156 14.9412 20.4964 16.0071H9.63335C10.8664 14.9428 11.8945 9.71342 12.1324 8.4196H17.6453ZM9.20192 15.7828C8.47685 15.7828 7.18702 12.0658 6.33874 8.4196H11.7101C11.0348 12.0642 9.92273 15.7828 9.20192 15.7828ZM5.80943 8.00323H0.438119C1.11576 4.35902 2.23011 0.640405 2.95072 0.640405C3.67558 0.640405 4.96319 4.3574 5.80943 8.00323ZM0.622526 0.416365H2.51908C1.64751 1.16899 0.876441 4.00121 0.415017 6.0564V0.624547C0.415017 0.509681 0.508032 0.416365 0.622526 0.416365ZM0.415017 15.7989V8.4196H5.91258C6.20723 9.69594 7.48288 14.9412 8.7636 16.0071H0.622526C0.508032 16.0071 0.415017 15.9138 0.415017 15.7989ZM21.4731 16.0071H21.3939C21.4934 15.9217 21.5902 15.8062 21.6806 15.6543V15.7989C21.6806 15.9138 21.5874 16.0071 21.4731 16.0071ZM21.6806 14.2969C21.5136 15.3866 21.1434 15.7828 20.9347 15.7828C20.2096 15.7828 18.9198 12.0658 18.0715 8.4196H21.6802V14.2969H21.6806ZM17.604 8.00323H12.2329C13.081 4.3574 14.3708 0.640405 15.0959 0.640405C15.8167 0.640405 16.9288 4.35902 17.604 8.00323ZM11.8065 8.00323H6.2356C5.94156 6.72629 4.66915 1.48249 3.38944 0.416365H14.6569C13.3768 1.48269 12.1014 6.72669 11.8065 8.00323Z" fill="#3A2C60"/>
<path d="M21.8882 3.50696C21.7735 3.50696 21.6807 3.60007 21.6807 3.71514V5.22446C21.6807 5.33953 21.7735 5.43265 21.8882 5.43265C22.0027 5.43265 22.0957 5.33953 22.0957 5.22446V3.71514C22.0957 3.60027 22.0027 3.50696 21.8882 3.50696Z" fill="#3A2C60"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

135
assets/icons/garageIcon.svg Normal file
View File

@ -0,0 +1,135 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.52252 13.1532H37.4775V39.8199H2.52252V13.1532Z" fill="url(#paint0_linear_4625_5577)"/>
<path d="M2.53027 21.4509H15.0588V39.9999H2.53027V21.4509Z" fill="url(#paint1_linear_4625_5577)"/>
<g clip-path="url(#clip0_4625_5577)">
<path d="M2.53027 20.1802H37.4697V30.8861H2.53027V20.1802Z" fill="url(#paint2_linear_4625_5577)"/>
<path d="M2.5882 12.6127H37.4902V16.7695H2.5882V12.6127Z" fill="url(#paint3_linear_4625_5577)"/>
<path d="M2.5882 15.9067H37.4902V20.0636H2.5882V15.9067Z" fill="url(#paint4_linear_4625_5577)"/>
<path d="M2.5882 19.2793H37.4902V23.4362H2.5882V19.2793Z" fill="url(#paint5_linear_4625_5577)"/>
<path d="M2.5882 22.5226H37.4902V26.6794H2.5882V22.5226Z" fill="url(#paint6_linear_4625_5577)"/>
<path d="M2.5882 25.8167H37.4902V29.9735H2.5882V25.8167Z" fill="url(#paint7_linear_4625_5577)"/>
<path d="M2.5882 29.1892H37.4902V33.3461H2.5882V29.1892Z" fill="url(#paint8_linear_4625_5577)"/>
<path d="M2.5882 32.4834H37.4902V36.6403H2.5882V32.4834Z" fill="url(#paint9_linear_4625_5577)"/>
<path d="M2.5882 35.7775H37.4902V39.9343H2.5882V35.7775Z" fill="url(#paint10_linear_4625_5577)"/>
</g>
<path d="M38.2162 9.93373L23.9216 1.01176C22.8408 0.337255 21.4204 0 20 0C18.5796 0 17.1592 0.337255 16.0784 1.01176L1.78376 9.93373C0.674196 10.6263 0 11.8418 0 13.1498V37.5124C0 38.8863 1.11373 40 2.48761 40C3.19333 40 3.76549 39.4278 3.76549 38.7221V16.6663C3.76549 15.2154 4.94173 14.0392 6.39255 14.0392H33.6075C35.0584 14.0392 36.2345 15.2154 36.2345 16.6663V38.7221C36.2345 39.4278 36.8067 40 37.5124 40C38.8863 40 40 38.8863 40 37.5124V13.1498C40 11.8418 39.3258 10.6263 38.2162 9.93373Z" fill="url(#paint11_linear_4625_5577)"/>
<path d="M38.2162 9.93373L23.9216 1.01177C22.8408 0.337255 21.4204 0 20 0C18.5796 0 17.1592 0.337255 16.0784 1.01177L1.78376 9.93373C0.674196 10.6263 0 11.8418 0 13.1498V16.9144C0 15.6064 0.674196 14.3908 1.78376 13.6983L16.0784 4.77624C17.1592 4.10173 18.5796 3.76447 20 3.76447C21.4204 3.76447 22.8408 4.10173 23.9216 4.77624L38.2162 13.6982C39.3258 14.3908 40 15.6064 40 16.9143V13.1498C40 11.8418 39.3258 10.6263 38.2162 9.93373Z" fill="url(#paint12_linear_4625_5577)"/>
<path d="M15.5309 8.89232H24.4691C24.9752 8.89232 25.3855 8.48205 25.3855 7.97601C25.3855 7.46989 24.9752 7.05969 24.4691 7.05969H15.5309C15.0248 7.05969 14.6146 7.46997 14.6146 7.97601C14.6146 8.48205 15.0248 8.89232 15.5309 8.89232Z" fill="url(#paint13_linear_4625_5577)"/>
<path d="M15.5309 12.2649H24.4691C24.9752 12.2649 25.3855 11.8546 25.3855 11.3486C25.3855 10.8424 24.9752 10.4323 24.4691 10.4323H15.5309C15.0248 10.4323 14.6146 10.8425 14.6146 11.3486C14.6146 11.8546 15.0248 12.2649 15.5309 12.2649Z" fill="url(#paint14_linear_4625_5577)"/>
<path d="M40 16.9145V37.5121C40 38.1992 39.7216 38.8211 39.2714 39.2713C38.8212 39.7215 38.1992 39.9999 37.5122 39.9999C36.8063 39.9999 36.2345 39.4282 36.2345 38.7223V16.6658C36.2345 15.2156 35.058 14.0392 33.6071 14.0392H6.39294C4.94196 14.0392 3.76549 15.2156 3.76549 16.6658V38.7223C3.76549 39.0752 3.62275 39.3945 3.39137 39.6258C3.16 39.8572 2.84078 39.9999 2.48784 39.9999C1.11373 39.9999 0 38.8862 0 37.5121V16.9145C0 15.6062 0.67451 14.3905 1.78353 13.698L16.0784 4.77641C17.1592 4.1019 18.5796 3.76465 20 3.76465C21.4204 3.76465 22.8408 4.1019 23.9216 4.77641L38.2165 13.698C39.3255 14.3905 40 15.6062 40 16.9145Z" fill="url(#paint15_linear_4625_5577)"/>
<path d="M20.0785 1.5697C17.7889 1.5697 15.5693 2.22868 13.6597 3.47551C13.1522 3.80688 13.0093 4.48696 13.3407 4.99449L15.1474 6.8068C15.0804 7.04649 15.112 7.31245 15.2582 7.53755L16.9387 9.24084C16.8755 9.43363 16.8963 9.65206 17.0145 9.83598L18.8084 11.5936C18.6893 12.034 18.8014 12.5241 19.1472 12.8699L20.3165 14.0392H33.6074C35.0583 14.0392 36.2345 15.2154 36.2345 16.6663V29.9572L40 33.7227V16.9851L26.4972 3.47551C24.5877 2.22876 22.3681 1.5697 20.0785 1.5697Z" fill="url(#paint16_linear_4625_5577)"/>
<path d="M22.8539 8.79254C22.0027 8.24564 21.0158 7.95654 20 7.95654C18.9843 7.95654 17.9974 8.24564 17.1461 8.79246C16.8216 9.00101 16.7276 9.43309 16.936 9.75756C17.1445 10.082 17.5766 10.1761 17.9011 9.96768C18.5267 9.5658 19.2525 9.35333 20 9.35333C20.7476 9.35333 21.4734 9.5658 22.0989 9.96768C22.2158 10.0427 22.3465 10.0786 22.4758 10.0786C22.7056 10.0786 22.9306 9.96525 23.064 9.75756C23.2725 9.43317 23.1785 9.00101 22.8539 8.79254Z" fill="url(#paint17_linear_4625_5577)"/>
<path d="M24.5563 6.21705C23.1995 5.3358 21.624 4.87 20 4.87C18.376 4.87 16.8005 5.3358 15.4437 6.21698C15.0278 6.48709 14.9096 7.04325 15.1798 7.45917C15.4499 7.87509 16.0061 7.99321 16.422 7.72309C17.4868 7.03149 18.7241 6.66592 20 6.66592C21.2759 6.66592 22.5133 7.03149 23.578 7.72309C23.7291 7.82121 23.8987 7.86811 24.0663 7.86811C24.3602 7.86811 24.6482 7.72396 24.8202 7.45917C25.0904 7.04325 24.9722 6.48717 24.5563 6.21705Z" fill="url(#paint18_linear_4625_5577)"/>
<path d="M26.4188 3.39709C24.5093 2.15027 22.2897 1.49121 20 1.49121C17.7104 1.49121 15.4908 2.15019 13.5812 3.39702C13.0737 3.72839 12.9308 4.40847 13.2622 4.916C13.5936 5.42353 14.2737 5.56635 14.7812 5.23498C16.333 4.2218 18.1377 3.68627 20 3.68627C21.8624 3.68627 23.667 4.2218 25.2188 5.23505C25.4039 5.35592 25.612 5.41372 25.8178 5.41372C26.1761 5.41372 26.5273 5.23851 26.7378 4.91607C27.0692 4.40854 26.9264 3.72847 26.4188 3.39709Z" fill="url(#paint19_linear_4625_5577)"/>
<path d="M20 13.1773C20.7274 13.1773 21.317 12.5876 21.317 11.8602C21.317 11.1329 20.7274 10.5432 20 10.5432C19.2726 10.5432 18.683 11.1329 18.683 11.8602C18.683 12.5876 19.2726 13.1773 20 13.1773Z" fill="url(#paint20_linear_4625_5577)"/>
<defs>
<linearGradient id="paint0_linear_4625_5577" x1="20" y1="23.2161" x2="20" y2="37.3131" gradientUnits="userSpaceOnUse">
<stop stop-color="#62DBFB"/>
<stop offset="0.1912" stop-color="#57D5FA"/>
<stop offset="0.5232" stop-color="#3BC5F7"/>
<stop offset="0.954" stop-color="#0DABF2"/>
<stop offset="1" stop-color="#08A9F1"/>
</linearGradient>
<linearGradient id="paint1_linear_4625_5577" x1="6.90196" y1="30.7254" x2="2.90196" y2="30.7254" gradientUnits="userSpaceOnUse">
<stop stop-color="#0593FC" stop-opacity="0"/>
<stop offset="0.6831" stop-color="#0389FC" stop-opacity="0.683"/>
<stop offset="1" stop-color="#0182FC"/>
</linearGradient>
<linearGradient id="paint2_linear_4625_5577" x1="20" y1="26.5723" x2="20" y2="21.2385" gradientUnits="userSpaceOnUse">
<stop stop-color="#0593FC" stop-opacity="0"/>
<stop offset="0.6831" stop-color="#0389FC" stop-opacity="0.683"/>
<stop offset="1" stop-color="#0182FC"/>
</linearGradient>
<linearGradient id="paint3_linear_4625_5577" x1="20.0392" y1="14.1813" x2="20.0392" y2="16.3788" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint4_linear_4625_5577" x1="20.0392" y1="17.4754" x2="20.0392" y2="19.6729" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint5_linear_4625_5577" x1="20.0392" y1="20.8479" x2="20.0392" y2="23.0454" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint6_linear_4625_5577" x1="20.0392" y1="24.0912" x2="20.0392" y2="26.2887" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint7_linear_4625_5577" x1="20.0392" y1="27.3853" x2="20.0392" y2="29.5828" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint8_linear_4625_5577" x1="20.0392" y1="30.7578" x2="20.0392" y2="32.9553" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint9_linear_4625_5577" x1="20.0392" y1="34.052" x2="20.0392" y2="36.2495" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint10_linear_4625_5577" x1="20.0392" y1="37.3461" x2="20.0392" y2="39.5436" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint11_linear_4625_5577" x1="9.048" y1="5.64996" x2="27.7147" y2="38.9049" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint12_linear_4625_5577" x1="20" y1="-5.80283" x2="20" y2="17.6317" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint13_linear_4625_5577" x1="20" y1="8.64785" x2="20" y2="6.96024" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint14_linear_4625_5577" x1="20" y1="12.0204" x2="20" y2="10.3328" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint15_linear_4625_5577" x1="13.8244" y1="14.8416" x2="10.2165" y2="7.70434" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint16_linear_4625_5577" x1="30.1222" y1="15.7451" x2="18.9065" y2="0.294096" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint17_linear_4625_5577" x1="19.4383" y1="7.77317" x2="20.3961" y2="10.5136" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint18_linear_4625_5577" x1="19.1947" y1="4.04396" x2="20.2856" y2="8.00827" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint19_linear_4625_5577" x1="19.157" y1="1.23215" x2="20.3277" y2="5.51576" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint20_linear_4625_5577" x1="18.7229" y1="10.5831" x2="20.8381" y2="12.6984" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<clipPath id="clip0_4625_5577">
<rect width="34.9599" height="27.3217" fill="white" transform="translate(2.53027 12.6127)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,29 @@
<svg width="50" height="49" viewBox="0 0 50 49" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25.0508 13.2076H14.9395C14.5289 13.2076 14.1961 12.8749 14.1961 12.4643C14.1961 12.0536 14.5288 11.7209 14.9395 11.7209H25.0508C25.4613 11.7209 25.7941 12.0536 25.7941 12.4643C25.7941 12.8749 25.4613 13.2076 25.0508 13.2076ZM9.98643 13.2076H0.743359C0.332812 13.2076 0 12.8749 0 12.4643C0 12.0536 0.332715 11.7209 0.743359 11.7209H9.98643C10.397 11.7209 10.7298 12.0536 10.7298 12.4643C10.7298 12.8749 10.397 13.2076 9.98643 13.2076Z" fill="#D9EEFF"/>
<path d="M10.7028 18.4107H3.71571C3.30516 18.4107 2.97235 18.078 2.97235 17.6674C2.97235 17.2568 3.30507 16.924 3.71571 16.924H10.7028C11.1134 16.924 11.4462 17.2567 11.4462 17.6674C11.4461 18.078 11.1134 18.4107 10.7028 18.4107Z" fill="#D9EEFF"/>
<path d="M5.97168 28.8144H0.743359C0.332812 28.8144 0 28.4817 0 28.0711C0 27.6604 0.332715 27.3277 0.743359 27.3277H5.97168C6.38223 27.3277 6.71504 27.6604 6.71504 28.0711C6.71504 28.4817 6.38223 28.8144 5.97168 28.8144Z" fill="#D9EEFF"/>
<path d="M11.717 34.0177H3.1454C2.73485 34.0177 2.40204 33.685 2.40204 33.2743C2.40204 32.8638 2.73475 32.531 3.1454 32.531H11.717C12.1275 32.531 12.4603 32.8637 12.4603 33.2743C12.4603 33.6849 12.1276 34.0177 11.717 34.0177Z" fill="#D9EEFF"/>
<path d="M8.94401 39.2209H5.30299C4.89244 39.2209 4.55963 38.8882 4.55963 38.4775C4.55963 38.067 4.89235 37.7342 5.30299 37.7342H8.94401C9.35455 37.7342 9.68737 38.0669 9.68737 38.4775C9.68727 38.8882 9.35455 39.2209 8.94401 39.2209Z" fill="#D9EEFF"/>
<path d="M20.6715 44.4241H9.68855C9.278 44.4241 8.94519 44.0914 8.94519 43.6808C8.94519 43.2702 9.27791 42.9374 9.68855 42.9374H20.6715C21.082 42.9374 21.4148 43.2701 21.4148 43.6808C21.4148 44.0913 21.0821 44.4241 20.6715 44.4241Z" fill="#D9EEFF"/>
<path d="M12.6245 23.6139H6.84828C6.43773 23.6139 6.10492 23.2812 6.10492 22.8706C6.10492 22.4599 6.43763 22.1272 6.84828 22.1272H12.6245C13.035 22.1272 13.3678 22.4599 13.3678 22.8706C13.3678 23.2812 13.035 23.6139 12.6245 23.6139Z" fill="#D9EEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.1365 4.34468L32.7766 11.0594C33.9959 11.2112 35.218 11.4836 36.4288 11.8826C37.6396 12.2815 38.7859 12.7901 39.8563 13.3913L42.2163 6.67652L35.1365 4.34468Z" fill="#EFF6FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.1587 0.754188L32.2849 3.40634C32.0967 3.97948 32.4086 4.60321 32.9817 4.7914L34.6618 5.34208L41.7387 7.67401L43.416 8.22753C43.9891 8.41581 44.6128 8.10106 44.801 7.52792L45.6748 4.87577C45.863 4.30263 45.5483 3.67889 44.9753 3.49071L34.5437 0.0545788C33.9706 -0.133702 33.3468 0.181044 33.1587 0.754188Z" fill="#375E7D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.4159 8.22741C43.9891 8.41569 44.6127 8.10095 44.801 7.5278L45.6747 4.87566C45.8629 4.30251 45.5482 3.67878 44.9752 3.4906L42.3905 2.63933C42.9637 2.82761 43.2783 3.45124 43.09 4.02439L42.2163 6.67654C42.0281 7.24968 41.4044 7.56433 40.8312 7.37614H40.8369L41.7388 7.674L43.4159 8.22741Z" fill="#2B4D66"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.75 47.3444C34.8387 50.6653 45.7084 45.1811 49.0292 35.0949C51.9538 26.2196 48.0571 16.7375 40.2075 12.3238C39.1371 11.7225 37.9909 11.214 36.78 10.8151C35.569 10.4162 34.347 10.1436 33.1277 9.99197C28.8714 9.46101 24.6545 10.3881 21.0864 12.4643C17.1673 14.7457 14.0319 18.4177 12.5036 23.0646C9.18007 33.1507 14.6641 44.0235 24.75 47.3444Z" fill="#375E7D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.454 14.8466C27.5932 12.2563 19.1228 16.5324 16.5325 24.3934C13.945 32.2545 18.2181 40.7252 26.0789 43.3128C33.9398 45.9031 42.4102 41.6298 45.0005 33.7688L45.0089 33.7407C47.5795 25.8881 43.3064 17.4314 35.454 14.8466Z" fill="#EFF6FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.454 14.8467L31.5488 26.7028C31.0965 28.0739 31.9675 29.3662 33.1249 29.8271L45.0089 33.7407C47.5795 25.8881 43.3063 17.4314 35.454 14.8467Z" fill="#EB5468"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.0088 33.7407C47.2621 26.8574 44.2559 19.5106 38.1931 16.0605C39.2579 19.238 39.8451 22.733 39.8451 26.4023C39.8451 28.2847 39.6906 30.1221 39.3956 31.8921L45.0088 33.7407Z" fill="#E5384F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M49.0292 35.0949C51.9538 26.2196 48.0571 16.7375 40.2075 12.3238C39.4209 11.8799 38.5921 11.4894 37.7267 11.1551C37.4149 11.0343 37.1003 10.9219 36.78 10.8151C36.4035 10.6915 36.027 10.5791 35.6477 10.4808C36.6647 12.189 37.5244 14.0629 38.1931 16.0604C44.2558 19.5105 47.2619 26.8574 45.0088 33.7407C45.0059 33.7491 45.0031 33.7576 45.0004 33.7688C43.3906 38.6518 39.5136 42.1496 34.9229 43.4785C33.6896 45.3271 32.2624 46.9567 30.6779 48.3137C38.7888 48.353 46.3546 43.2172 49.0292 35.0949Z" fill="#2B4D66"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.9229 43.4785C39.5135 42.1496 43.3906 38.6517 45.0004 33.7688L45.0088 33.7407L39.3955 31.8921C38.8729 35.0359 37.9121 37.9719 36.5972 40.5931C36.0888 41.6046 35.5297 42.5682 34.9229 43.4785Z" fill="#D9EEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.2076 12.3237L41.7387 7.67401L40.8313 7.37616L39.1541 6.82265L37.7268 11.155C38.5921 11.4893 39.4209 11.8799 40.2076 12.3237Z" fill="#D9EEFF"/>
<path d="M26.0958 44.0056C26.0188 44.0056 25.9404 43.9935 25.8631 43.968C25.4732 43.8396 25.2612 43.4194 25.3898 43.0295L26.1905 40.5992C26.3188 40.2092 26.7386 39.9971 27.129 40.1258C27.519 40.2543 27.731 40.6745 27.6024 41.0644L26.8017 43.4947C26.6987 43.8075 26.408 44.0056 26.0958 44.0056Z" fill="#375E7D"/>
<path d="M18.9963 25.9181C18.9192 25.9181 18.8407 25.906 18.7633 25.8804L16.336 25.0796C15.9461 24.9511 15.7343 24.5308 15.863 24.1408C15.9916 23.7511 16.4114 23.5388 16.8018 23.6679L19.2292 24.4687C19.619 24.5972 19.8308 25.0175 19.7021 25.4074C19.599 25.7199 19.3085 25.9181 18.9963 25.9181Z" fill="#375E7D"/>
<path d="M25.1917 18.7256C24.9202 18.7256 24.6586 18.5762 24.5277 18.3175L23.373 16.0333C23.1877 15.667 23.3347 15.2198 23.701 15.0345C24.0674 14.8496 24.5146 14.9963 24.6997 15.3626L25.8545 17.6468C26.0398 18.0131 25.8928 18.4602 25.5265 18.6455C25.419 18.6998 25.3045 18.7256 25.1917 18.7256Z" fill="#375E7D"/>
<path d="M37.5139 43.1515C37.2421 43.1515 36.9803 43.0019 36.8496 42.7428L35.6978 40.4586C35.5129 40.0921 35.6602 39.645 36.0268 39.4602C36.3932 39.2753 36.8403 39.4225 37.0251 39.7892L38.177 42.0734C38.3618 42.4399 38.2146 42.887 37.848 43.0718C37.7406 43.1259 37.6264 43.1515 37.5139 43.1515Z" fill="#375E7D"/>
<path d="M17.4207 36.5353C17.1489 36.5353 16.8871 36.3857 16.7564 36.1265C16.5716 35.76 16.7188 35.313 17.0854 35.1281L19.3696 33.9762C19.736 33.791 20.1832 33.9385 20.368 34.3052C20.5528 34.6717 20.4056 35.1187 20.0389 35.3035L17.7548 36.4555C17.6474 36.5096 17.5333 36.5353 17.4207 36.5353Z" fill="#375E7D"/>
<path d="M28.7476 28.1964C28.5688 28.1964 28.3896 28.1323 28.247 28.0025L22.85 23.0829C22.5467 22.8063 22.5249 22.3362 22.8014 22.0328C23.0779 21.7294 23.548 21.7077 23.8515 21.9842L29.2485 26.9037C29.5518 27.1804 29.5736 27.6504 29.297 27.9538C29.1505 28.1147 28.9494 28.1964 28.7476 28.1964Z" fill="#375E7D"/>
<path d="M31.4073 35.0686C31.0354 35.0686 30.7143 34.79 30.67 34.4114L30.3441 31.6216C30.2965 31.2139 30.5884 30.8447 30.9962 30.7971C31.4024 30.7501 31.7731 31.0412 31.8207 31.4491L32.1466 34.239C32.1942 34.6467 31.9023 35.0158 31.4945 35.0635C31.4653 35.0668 31.4362 35.0686 31.4073 35.0686Z" fill="#375E7D"/>
<path d="M30.7842 44.8168C29.1281 44.8168 27.4649 44.552 25.8462 44.0187C17.6097 41.3075 13.1147 32.3994 15.8264 24.1612C17.1414 20.1702 19.9313 16.93 23.6818 15.0373C27.4331 13.1443 31.6965 12.8261 35.6866 14.1409C43.9069 16.8469 48.4056 25.7377 45.7183 33.9632L45.7125 33.9826C45.7106 33.989 45.7086 33.9953 45.7066 34.0017C44.3916 37.9922 41.6018 41.2319 37.851 43.1239C35.6214 44.2482 33.2107 44.8168 30.7842 44.8168ZM30.7519 14.8303C28.554 14.8303 26.3711 15.3453 24.3517 16.3644C20.9554 18.0782 18.4292 21.0123 17.2384 24.6261C14.783 32.0855 18.853 40.1517 26.3112 42.6066C29.9246 43.7974 33.785 43.5096 37.1814 41.7964C40.5747 40.0847 43.0995 37.1548 44.2915 33.5454L44.297 33.5271C44.2987 33.5213 44.3006 33.5153 44.3025 33.5096C46.7413 26.0592 42.6677 18.0039 35.2216 15.5527C35.2215 15.5527 35.2214 15.5526 35.2213 15.5526C33.7565 15.0699 32.2507 14.8303 30.7519 14.8303Z" fill="#FFC250"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M31.5489 26.7028C30.2509 26.2758 28.8518 26.981 28.4247 28.279C27.9977 29.577 28.7029 30.9762 30.0008 31.4032C31.2988 31.8303 32.6979 31.1251 33.1249 29.8271C33.552 28.5291 32.8468 27.1299 31.5489 26.7028Z" fill="#FFE07D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.1249 29.8271C33.552 28.5291 32.8468 27.1299 31.5489 26.7029C30.8718 26.4809 30.1666 26.5652 29.5851 26.8826C30.7847 27.3658 31.4197 28.706 31.0095 29.9534C30.8044 30.5715 30.3802 31.0575 29.8492 31.3497C29.8998 31.3694 29.9504 31.3863 30.0009 31.4031C31.2989 31.8303 32.698 31.1251 33.1249 29.8271Z" fill="#FFE07D"/>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -0,0 +1,11 @@
<svg width="46" height="50" viewBox="0 0 46 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.15027 2.12148V47.8785C4.15027 49.0502 5.10007 50 6.27175 50C7.44343 50 8.39324 49.0502 8.39324 47.8785V2.12148C8.39314 0.949805 7.44333 0 6.27175 0C5.10017 0 4.15027 0.949805 4.15027 2.12148Z" fill="#655E67"/>
<path d="M20.7635 2.12148V47.8785C20.7635 49.0502 21.7134 50 22.885 50C24.0567 50 25.0065 49.0502 25.0065 47.8785V2.12148C25.0065 0.949805 24.0567 0 22.885 0C21.7134 0 20.7635 0.949805 20.7635 2.12148Z" fill="#655E67"/>
<path d="M37.3768 2.12148V47.8785C37.3768 49.0502 38.3266 50 39.4983 50C40.67 50 41.6198 49.0502 41.6198 47.8785V2.12148C41.6198 0.949805 40.67 0 39.4983 0C38.3266 0 37.3768 0.949805 37.3768 2.12148Z" fill="#655E67"/>
<path d="M0 15.1651V20.7505C0 21.3062 0.450391 21.7566 1.00605 21.7566H11.5375C12.0932 21.7566 12.5436 21.3062 12.5436 20.7505V15.1651C12.5436 14.6094 12.0932 14.159 11.5375 14.159H1.00605C0.450391 14.159 0 14.6094 0 15.1651Z" fill="#717ED4"/>
<path d="M16.6133 29.2496V34.835C16.6133 35.3907 17.0637 35.8411 17.6193 35.8411H28.1508C28.7064 35.8411 29.1568 35.3907 29.1568 34.835V29.2496C29.1568 28.6939 28.7064 28.2435 28.1508 28.2435H17.6193C17.0638 28.2436 16.6133 28.694 16.6133 29.2496Z" fill="#F9BF64"/>
<path d="M33.2266 15.1651V20.7505C33.2266 21.3062 33.677 21.7566 34.2327 21.7566H44.7641C45.3198 21.7566 45.7702 21.3062 45.7702 20.7505V15.1651C45.7702 14.6094 45.3198 14.159 44.7641 14.159H34.2326C33.677 14.159 33.2266 14.6094 33.2266 15.1651Z" fill="#DF646E"/>
<path d="M44.7641 14.159H41.746C42.3017 14.159 42.7521 14.6094 42.7521 15.1651V20.7505C42.7521 21.3061 42.3017 21.7566 41.746 21.7566H44.7641C45.3198 21.7566 45.7702 21.3062 45.7702 20.7505V15.1651C45.7702 14.6094 45.3198 14.159 44.7641 14.159Z" fill="#D82F3C"/>
<path d="M28.1508 28.2435H25.1327C25.6884 28.2435 26.1387 28.6939 26.1387 29.2496V34.835C26.1387 35.3907 25.6884 35.8411 25.1327 35.8411H28.1508C28.7064 35.8411 29.1568 35.3907 29.1568 34.835V29.2496C29.1568 28.6939 28.7063 28.2435 28.1508 28.2435Z" fill="#E9A761"/>
<path d="M11.5375 14.159H8.51941C9.07507 14.159 9.52546 14.6094 9.52546 15.1651V20.7505C9.52546 21.3061 9.07507 21.7566 8.51941 21.7566H11.5375C12.0931 21.7566 12.5435 21.3062 12.5435 20.7505V15.1651C12.5434 14.6094 12.093 14.159 11.5375 14.159Z" fill="#5766CC"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,28 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.8179 47.6354C36.972 47.6354 47.6355 36.9719 47.6355 23.8178C47.6355 10.6636 36.972 9.15527e-05 23.8179 9.15527e-05C10.6637 9.15527e-05 0.000183105 10.6636 0.000183105 23.8178C0.000183105 36.9719 10.6637 47.6354 23.8179 47.6354Z" fill="#F07281"/>
<path d="M24.8239 47.6147C24.4909 47.6287 24.1549 47.6357 23.8179 47.6357C10.664 47.6357 0 36.9718 0 23.8179C0 10.664 10.664 0 23.8179 0C24.1549 0 24.4909 0.00703125 24.8239 0.0210938C12.1367 0.548242 2.01201 11.001 2.01201 23.8179C2.01201 36.6348 12.1367 47.0875 24.8239 47.6147Z" fill="#EB5569"/>
<path d="M23.8181 44.5108C35.2465 44.5108 44.5111 35.2463 44.5111 23.8178C44.5111 12.3894 35.2465 3.12488 23.8181 3.12488C12.3897 3.12488 3.12512 12.3894 3.12512 23.8178C3.12512 35.2463 12.3897 44.5108 23.8181 44.5108Z" fill="#EAF6FF"/>
<path d="M25.3269 44.4567C24.8289 44.4929 24.3248 44.511 23.8178 44.511C12.3892 44.511 3.12463 35.2465 3.12463 23.8178C3.12463 12.3892 12.3893 3.12468 23.8179 3.12468C24.3249 3.12468 24.8289 3.14275 25.327 3.17898C14.6026 3.95173 6.1428 12.8964 6.1428 23.8178C6.1428 34.7393 14.6026 43.6841 25.3269 44.4567Z" fill="#D8ECFE"/>
<path d="M22.5243 11.7706L23.448 11.1759C23.6734 11.0308 23.9627 11.0308 24.1881 11.1759L25.1119 11.7706C25.2793 11.8785 25.3806 12.0641 25.3806 12.2633V24.0946H22.2556V12.2633C22.2555 12.0641 22.3568 11.8786 22.5243 11.7706Z" fill="#5680A6"/>
<path d="M24.8239 11.5855L24.2675 11.9437V24.0945H22.2554V12.3165C22.2554 12.0841 22.3735 11.8676 22.5689 11.7418L23.4476 11.176C23.673 11.0309 23.9625 11.0309 24.1879 11.176L24.8239 11.5855Z" fill="#497090"/>
<path d="M33.5805 24.188L33.0147 25.0668C32.8888 25.2622 32.6724 25.3803 32.44 25.3803H23.8179V22.2556H32.44C32.6724 22.2556 32.8889 22.3737 33.0147 22.5691L33.5805 23.4479C33.7256 23.6733 33.7256 23.9626 33.5805 24.188Z" fill="#5680A6"/>
<path d="M28.018 23.8179C28.018 24.3702 27.9114 24.8974 27.7162 25.3803H23.8177V22.2556H27.7162C27.9114 22.7385 28.018 23.2656 28.018 23.8179Z" fill="#497090"/>
<path d="M23.818 26.0059C25.0265 26.0059 26.0061 25.0263 26.0061 23.8179C26.0061 22.6094 25.0265 21.6298 23.818 21.6298C22.6096 21.6298 21.6299 22.6094 21.6299 23.8179C21.6299 25.0263 22.6096 26.0059 23.818 26.0059Z" fill="#F07281"/>
<path d="M24.8239 25.7606C24.5231 25.9175 24.181 26.0061 23.8178 26.0061C22.6096 26.0061 21.6298 25.0262 21.6298 23.818C21.6298 22.6098 22.6096 21.6299 23.8178 21.6299C24.181 21.6299 24.5231 21.7185 24.8239 21.8754C24.1217 22.2386 23.6418 22.973 23.6418 23.8181C23.6418 24.6632 24.1217 25.3974 24.8239 25.7606Z" fill="#EB5569"/>
<path d="M49.3331 41.0217V39.4608C49.3331 39.1491 49.1221 38.8768 48.8203 38.7989L47.1254 38.3615C46.9368 37.6012 46.637 36.8848 46.2431 36.2311L47.1322 34.7235C47.2906 34.455 47.2471 34.1134 47.0267 33.8929L45.923 32.7891C45.7026 32.5687 45.3609 32.5253 45.0923 32.6837L43.5847 33.5727C42.9311 33.1788 42.2147 32.8791 41.4543 32.6904L41.0169 30.9956C40.939 30.6937 40.6667 30.4828 40.355 30.4828H38.7942C38.4825 30.4828 38.2102 30.6937 38.1323 30.9956L37.6949 32.6904C36.9345 32.8791 36.2181 33.1789 35.5645 33.5727L34.0569 32.6837C33.7883 32.5253 33.4467 32.5687 33.2262 32.7891L32.1225 33.8929C31.9021 34.1133 31.8587 34.455 32.017 34.7235L32.9061 36.2311C32.5122 36.8848 32.2124 37.6012 32.0238 38.3615L30.329 38.7989C30.0271 38.8768 29.8162 39.1491 29.8162 39.4608V41.0217C29.8162 41.3334 30.0271 41.6057 30.329 41.6836L32.0238 42.121C32.2124 42.8813 32.5123 43.5977 32.9061 44.2514L32.017 45.759C31.8586 46.0275 31.9021 46.3691 32.1225 46.5896L33.2262 47.6933C33.4466 47.9138 33.7883 47.9571 34.0569 47.7988L35.5645 46.9098C36.2181 47.3037 36.9345 47.6034 37.6949 47.7921L38.1323 49.4869C38.2102 49.7888 38.4825 49.9997 38.7942 49.9997H40.355C40.6667 49.9997 40.939 49.7888 41.0169 49.4869L41.4543 47.7921C42.2147 47.6034 42.9311 47.3036 43.5847 46.9098L45.0923 47.7988C45.3609 47.9572 45.7025 47.9138 45.923 47.6933L47.0267 46.5896C47.2471 46.3692 47.2905 46.0275 47.1322 45.759L46.2431 44.2514C46.6371 43.5977 46.9368 42.8813 47.1254 42.121L48.8203 41.6836C49.1221 41.6057 49.3331 41.3334 49.3331 41.0217Z" fill="#88B4F5"/>
<path d="M31.8289 38.9315V41.5513L34.0362 42.1207C34.2243 42.8812 34.5241 43.5976 34.9185 44.2515L33.7606 46.2152L34.8662 47.3209L34.0568 47.7983C33.7882 47.9567 33.4465 47.9134 33.2261 47.6929L32.1229 46.5896C31.9025 46.3692 31.8591 46.0275 32.0174 45.7591L32.9064 44.2515C32.512 43.5976 32.2122 42.8812 32.0241 42.1207L30.3296 41.6836C30.0278 41.6058 29.8168 41.3334 29.8168 41.0217V39.4609C29.8168 39.1493 30.0277 38.877 30.3294 38.7991L32.0242 38.3611C32.2122 37.6016 32.512 36.8843 32.9065 36.2313L32.0174 34.7235C31.8591 34.4551 31.9025 34.1135 32.1228 33.8931L33.2262 32.7891C33.4466 32.5685 33.7884 32.5251 34.057 32.6835L34.8662 33.1608L33.7606 34.2676L34.9185 36.2313C34.5242 36.8843 34.2244 37.6016 34.0362 38.3611L31.8289 38.9315Z" fill="#6EA2F2"/>
<path d="M39.7071 47.7918L40.2766 50H38.7941C38.4823 50 38.2101 49.7891 38.1322 49.4871L37.695 47.7918C37.3379 47.7043 36.9897 47.5906 36.6538 47.4538L37.5764 46.9096C38.2303 47.3038 38.9466 47.6036 39.7071 47.7918Z" fill="#6EA2F2"/>
<path d="M38.7941 30.4829H40.2766L39.7071 32.6901C38.9466 32.8793 38.2303 33.1791 37.5764 33.5725L36.6538 33.0282C36.9898 32.8924 37.3379 32.7787 37.695 32.6902L38.1321 30.9958C38.2101 30.6938 38.4824 30.4829 38.7941 30.4829Z" fill="#6EA2F2"/>
<path d="M39.5747 44.9442C42.1721 44.9442 44.2778 42.8386 44.2778 40.2412C44.2778 37.6438 42.1721 35.5382 39.5747 35.5382C36.9773 35.5382 34.8717 37.6438 34.8717 40.2412C34.8717 42.8386 36.9773 44.9442 39.5747 44.9442Z" fill="#5680A6"/>
<path d="M41.0834 44.6971C40.6096 44.8581 40.1015 44.9446 39.5743 44.9446C36.9777 44.9446 34.8721 42.8389 34.8721 40.2414C34.8721 37.6438 36.9777 35.5382 39.5743 35.5382C40.1015 35.5382 40.6095 35.6247 41.0834 35.7856C39.2272 36.4144 37.8902 38.1719 37.8902 40.2414C37.8902 42.3108 39.2272 44.0683 41.0834 44.6971Z" fill="#497090"/>
<path d="M23.8181 8.84687C23.4014 8.84687 23.0636 8.50908 23.0636 8.09238V6.14326C23.0636 5.72656 23.4014 5.38876 23.8181 5.38876C24.2348 5.38876 24.5726 5.72656 24.5726 6.14326V8.09228C24.5726 8.50898 24.2348 8.84687 23.8181 8.84687Z" fill="#88B4F5"/>
<path d="M23.8181 42.2471C23.4014 42.2471 23.0636 41.9093 23.0636 41.4926V39.5435C23.0636 39.1268 23.4014 38.789 23.8181 38.789C24.2348 38.789 24.5726 39.1268 24.5726 39.5435V41.4926C24.5726 41.9092 24.2348 42.2471 23.8181 42.2471Z" fill="#88B4F5"/>
<path d="M8.09249 24.5725H6.14347C5.72677 24.5725 5.38898 24.2347 5.38898 23.818C5.38898 23.4013 5.72677 23.0635 6.14347 23.0635H8.09249C8.50919 23.0635 8.84699 23.4013 8.84699 23.818C8.84699 24.2347 8.50919 24.5725 8.09249 24.5725Z" fill="#88B4F5"/>
<path d="M41.4927 24.5725H39.5437C39.1269 24.5725 38.7892 24.2347 38.7892 23.818C38.7892 23.4013 39.127 23.0635 39.5437 23.0635H41.4927C41.9095 23.0635 42.2472 23.4013 42.2472 23.818C42.2472 24.2347 41.9094 24.5725 41.4927 24.5725Z" fill="#88B4F5"/>
<path d="M8.51212 33.4099C8.25138 33.4099 7.99777 33.2746 7.85802 33.0325C7.64962 32.6716 7.77325 32.2101 8.13419 32.0018L9.82208 31.0273C10.1827 30.8191 10.6443 30.9425 10.8527 31.3035C11.0611 31.6643 10.9375 32.1258 10.5766 32.3341L8.88868 33.3086C8.76993 33.3773 8.64015 33.4099 8.51212 33.4099Z" fill="#88B4F5"/>
<path d="M37.4376 16.7098C37.1769 16.7098 36.9233 16.5744 36.7835 16.3323C36.5751 15.9715 36.6989 15.51 37.0597 15.3017L38.7476 14.3272C39.1083 14.1189 39.5699 14.2424 39.7783 14.6033C39.9867 14.9642 39.8629 15.4257 39.5021 15.634L37.8142 16.6085C37.6954 16.6772 37.5656 16.7098 37.4376 16.7098Z" fill="#88B4F5"/>
<path d="M10.1986 16.7097C10.0706 16.7097 9.94093 16.6771 9.82208 16.6085L8.13419 15.634C7.77325 15.4256 7.64962 14.9641 7.85802 14.6033C8.06632 14.2424 8.52775 14.1186 8.88868 14.3271L10.5766 15.3016C10.9375 15.51 11.0611 15.9715 10.8527 16.3323C10.713 16.5744 10.4594 16.7097 10.1986 16.7097Z" fill="#88B4F5"/>
<path d="M14.9801 39.8791C14.8521 39.8791 14.7224 39.8465 14.6036 39.7779C14.2426 39.5695 14.119 39.108 14.3274 38.7472L15.3019 37.0593C15.5102 36.6984 15.9717 36.5746 16.3326 36.7831C16.6935 36.9915 16.8171 37.453 16.6087 37.8138L15.6342 39.5017C15.4945 39.7438 15.2409 39.8791 14.9801 39.8791Z" fill="#88B4F5"/>
<path d="M31.6802 10.9538C31.5522 10.9538 31.4225 10.9212 31.3037 10.8525C30.9428 10.6442 30.8191 10.1827 31.0275 9.82184L32.002 8.13395C32.2103 7.77301 32.6716 7.64938 33.0327 7.85778C33.3935 8.06608 33.5172 8.5276 33.3088 8.88844L32.3343 10.5763C32.1946 10.8184 31.941 10.9538 31.6802 10.9538Z" fill="#88B4F5"/>
<path d="M15.956 10.9538C15.6953 10.9538 15.4416 10.8184 15.3019 10.5763L14.3274 8.88845C14.119 8.52761 14.2426 8.06609 14.6036 7.85779C14.9643 7.64939 15.4259 7.77303 15.6342 8.13396L16.6087 9.82185C16.8171 10.1827 16.6935 10.6442 16.3326 10.8525C16.2138 10.9211 16.084 10.9538 15.956 10.9538Z" fill="#88B4F5"/>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -0,0 +1,3 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="7.5" cy="7.5" r="5" stroke="#FF4756" stroke-width="5"/>
</svg>

After

Width:  |  Height:  |  Size: 171 B

View File

@ -0,0 +1,3 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="7.5" cy="7.5" r="5" stroke="#023DFE" stroke-opacity="0.6" stroke-width="5"/>
</svg>

After

Width:  |  Height:  |  Size: 192 B

View File

@ -0,0 +1,27 @@
<svg width="290" height="290" viewBox="0 0 290 290" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_4096_940)">
<rect x="20" y="20" width="250" height="250" rx="100" fill="#EDEDED"/>
<path d="M188.067 144.007C188.067 169.96 167.01 191 141.034 191C115.058 191 94 169.96 94 144.007C94 121.065 130.751 80.7942 139.281 71.7567C140.233 70.7478 141.835 70.7478 142.787 71.7567C151.317 80.7945 188.067 121.065 188.067 144.007Z" fill="#B3DAFE"/>
<path d="M142.787 71.7567C141.835 70.7478 140.233 70.7478 139.281 71.7567C138.759 72.3096 138.13 72.9809 137.412 73.7562C148.433 85.6575 180.824 122.468 180.824 144.006C180.824 168.743 161.696 189.015 137.412 190.862C138.607 190.953 139.815 191 141.034 191C167.01 191 188.068 169.96 188.068 144.006C188.068 121.065 151.317 80.7945 142.787 71.7567Z" fill="#8AC9FE"/>
<path d="M187.944 147.412C174.836 141.859 160.63 142.943 123.956 150.612C115.699 152.338 106.251 154.41 95.7856 156.876C101.386 176.573 119.524 191 141.034 191C165.864 191 186.197 171.776 187.944 147.412Z" fill="#60B7FF"/>
<path d="M171.214 128.586C184.882 128.586 195.962 117.506 195.962 103.837C195.962 90.1692 184.882 79.0889 171.214 79.0889C157.545 79.0889 146.465 90.1692 146.465 103.837C146.465 117.506 157.545 128.586 171.214 128.586Z" fill="#97D729"/>
<path d="M171.312 79.057C170.081 79.057 168.872 79.1482 167.69 79.3219C179.626 81.0743 188.79 91.356 188.79 103.779C188.79 116.202 179.626 126.484 167.69 128.236C168.872 128.41 170.081 128.501 171.312 128.501C184.965 128.501 196.034 117.433 196.034 103.779C196.034 90.1253 184.965 79.057 171.312 79.057Z" fill="#8BC727"/>
<path d="M168.515 114.479C167.115 114.479 165.798 113.933 164.808 112.943L157.249 105.383C155.713 103.848 155.713 101.359 157.249 99.8238C158.784 98.2886 161.273 98.2881 162.808 99.8238L168.515 105.531L179.816 94.2307C181.351 92.6955 183.84 92.6955 185.375 94.2307C186.911 95.7658 186.911 98.2551 185.375 99.79L172.222 112.943C171.232 113.934 169.915 114.479 168.515 114.479Z" fill="#F9F7F8"/>
<path d="M187.944 147.39C185.707 146.442 183.227 145.694 180.811 145.145C180.706 149.723 179.999 154.036 178.64 158.186L184.447 162.112C185.371 159.949 186.219 157.298 186.921 154.209C187.492 151.698 187.795 149.396 187.944 147.39Z" fill="#26A6FE"/>
<path d="M158.594 154.258C134.004 150.208 121.183 134.478 95.1665 136.178C94.4172 138.944 94 141.573 94 144.007C94 169.96 115.058 191 141.034 191C163.857 191 182.881 174.757 187.163 153.21C175.527 155.808 166.006 155.478 158.594 154.258Z" fill="#0593FC"/>
<path d="M179.633 154.541C175.105 174.288 158.13 189.291 137.395 190.861C138.596 190.953 139.809 191 141.034 191C163.857 191 182.881 174.757 187.163 153.21C184.546 153.794 182.036 154.229 179.633 154.541Z" fill="#0182FC"/>
<path d="M119.354 205.825H122.193V219H119.495L113.571 210.809V219H110.732V205.825H113.431L119.354 214.034V205.825ZM133.602 217.646C132.57 218.684 131.27 219.202 129.699 219.202C128.129 219.202 126.828 218.684 125.797 217.646C124.766 216.604 124.25 215.347 124.25 213.876C124.25 212.405 124.766 211.154 125.797 210.123C126.822 209.098 128.123 208.585 129.699 208.585C131.275 208.585 132.576 209.098 133.602 210.123C134.633 211.154 135.148 212.405 135.148 213.876C135.148 215.347 134.633 216.604 133.602 217.646ZM129.69 211.046V211.055C128.876 211.055 128.223 211.321 127.73 211.854C127.238 212.388 126.992 213.067 126.992 213.894C126.992 214.708 127.238 215.388 127.73 215.933C128.223 216.478 128.876 216.75 129.69 216.75C130.517 216.75 131.176 216.48 131.668 215.941C132.16 215.402 132.406 214.72 132.406 213.894C132.406 213.067 132.16 212.385 131.668 211.846C131.176 211.312 130.517 211.046 129.69 211.046ZM139.815 210.844V210.835C140.694 209.394 141.948 208.673 143.577 208.673V211.573H143.252C142.262 211.573 141.441 211.846 140.791 212.391C140.141 212.936 139.815 213.832 139.815 215.08V219H137.073V208.796H139.815V210.844ZM158.141 208.611H158.149C159.251 208.611 160.136 208.995 160.804 209.763C161.472 210.524 161.806 211.559 161.806 212.865V219H159.072V213.226C159.072 212.563 158.888 212.039 158.519 211.652C158.149 211.266 157.66 211.072 157.051 211.072C156.465 211.072 155.964 211.292 155.548 211.731C155.138 212.165 154.933 212.728 154.933 213.419V219H152.199V213.261C152.199 212.581 152.015 212.048 151.646 211.661C151.276 211.274 150.799 211.081 150.213 211.081C149.604 211.081 149.094 211.327 148.684 211.819C148.273 212.306 148.068 212.851 148.068 213.454V219H145.326V208.796H148.068V210.237C149.053 209.159 150.131 208.614 151.303 208.603C151.994 208.603 152.609 208.77 153.148 209.104C153.688 209.438 154.115 209.903 154.432 210.501C155.539 209.241 156.775 208.611 158.141 208.611ZM170.621 219L170.604 217.84C169.959 218.742 168.913 219.19 167.466 219.185C166.294 219.185 165.359 218.909 164.662 218.358C163.959 217.802 163.607 217.017 163.607 216.003C163.607 214.972 164.023 214.166 164.855 213.586C165.688 213.006 166.663 212.716 167.782 212.716C168.702 212.716 169.616 212.848 170.524 213.111C170.56 211.635 169.798 210.896 168.239 210.896C167.618 210.896 166.982 210.976 166.332 211.134C165.682 211.292 165.172 211.459 164.803 211.635L164.135 209.64C165.594 208.942 167.094 208.594 168.635 208.594C170.217 208.594 171.386 208.98 172.142 209.754C172.897 210.527 173.275 211.702 173.275 213.278V219H170.621ZM168.248 217.225L168.239 217.233C168.884 217.233 169.429 217.078 169.874 216.768C170.313 216.463 170.533 216.018 170.533 215.432V214.755C169.889 214.526 169.203 214.412 168.477 214.412C167.867 214.412 167.357 214.535 166.947 214.781C166.537 215.027 166.332 215.37 166.332 215.81C166.332 216.243 166.514 216.589 166.877 216.847C167.234 217.099 167.691 217.225 168.248 217.225ZM175.657 219V205.034H178.399V219H175.657Z" fill="#0593FC"/>
</g>
<defs>
<filter id="filter0_d_4096_940" x="0" y="0" width="290" height="290" 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="10"/>
<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.35 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4096_940"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4096_940" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1,117 @@
<svg width="290" height="290" viewBox="0 0 290 290" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_4111_515)">
<rect x="20" y="20" width="250" height="250" rx="100" fill="#EDEDED"/>
<path d="M92.5676 124.459H197.432V204.459H92.5676V124.459Z" fill="url(#paint0_linear_4111_515)"/>
<path d="M92.5908 149.353H130.176V205H92.5908V149.353Z" fill="url(#paint1_linear_4111_515)"/>
<g clip-path="url(#clip0_4111_515)">
<path d="M92.7646 117.568H197.471V130.038H92.7646V117.568Z" fill="url(#paint2_linear_4111_515)"/>
<path d="M92.7646 127.45H197.471V139.921H92.7646V127.45Z" fill="url(#paint3_linear_4111_515)"/>
<path d="M92.7646 137.332H197.471V149.803H92.7646V137.332Z" fill="url(#paint4_linear_4111_515)"/>
</g>
<path d="M199.649 114.801L156.765 88.0353C153.522 86.0118 149.261 85 145 85C140.739 85 136.478 86.0118 133.235 88.0353L90.3513 114.801C87.0226 116.879 85 120.525 85 124.449V197.537C85 201.659 88.3412 205 92.4628 205C94.58 205 96.2965 203.284 96.2965 201.166V134.999C96.2965 130.646 99.8252 127.118 104.178 127.118H185.822C190.175 127.118 193.704 130.646 193.704 134.999V201.166C193.704 203.284 195.42 205 197.537 205C201.659 205 205 201.659 205 197.537V124.449C205 120.525 202.977 116.879 199.649 114.801Z" fill="url(#paint5_linear_4111_515)"/>
<path d="M199.649 114.801L156.765 88.0353C153.522 86.0118 149.261 85 145 85C140.739 85 136.478 86.0118 133.235 88.0353L90.3513 114.801C87.0226 116.879 85 120.525 85 124.449V135.743C85 131.819 87.0226 128.172 90.3513 126.095L133.235 99.3287C136.478 97.3052 140.739 96.2934 145 96.2934C149.261 96.2934 153.522 97.3052 156.765 99.3287L199.649 126.095C202.977 128.172 205 131.819 205 135.743V124.449C205 120.525 202.977 116.879 199.649 114.801Z" fill="url(#paint6_linear_4111_515)"/>
<path d="M131.593 111.677H158.407C159.926 111.677 161.156 110.446 161.156 108.928C161.156 107.41 159.926 106.179 158.407 106.179H131.593C130.074 106.179 128.844 107.41 128.844 108.928C128.844 110.446 130.075 111.677 131.593 111.677Z" fill="url(#paint7_linear_4111_515)"/>
<path d="M131.593 121.795H158.407C159.926 121.795 161.156 120.564 161.156 119.046C161.156 117.527 159.926 116.297 158.407 116.297H131.593C130.074 116.297 128.844 117.528 128.844 119.046C128.844 120.564 130.075 121.795 131.593 121.795Z" fill="url(#paint8_linear_4111_515)"/>
<path d="M205 135.744V197.536C205 199.598 204.165 201.464 202.814 202.814C201.464 204.165 199.598 205 197.536 205C195.419 205 193.704 203.285 193.704 201.167V134.998C193.704 130.647 190.174 127.118 185.821 127.118H104.179C99.8259 127.118 96.2965 130.647 96.2965 134.998V201.167C96.2965 202.226 95.8682 203.184 95.1741 203.878C94.48 204.572 93.5224 205 92.4635 205C88.3412 205 85 201.659 85 197.536V135.744C85 131.819 87.0235 128.172 90.3506 126.094L133.235 99.3294C136.478 97.3059 140.739 96.2941 145 96.2941C149.261 96.2941 153.522 97.3059 156.765 99.3294L199.649 126.094C202.976 128.172 205 131.819 205 135.744Z" fill="url(#paint9_linear_4111_515)"/>
<path d="M145.236 89.7092C138.367 89.7092 131.708 91.6861 125.979 95.4266C124.456 96.4207 124.028 98.4609 125.022 99.9835L130.442 105.42C130.241 106.14 130.336 106.937 130.775 107.613L135.816 112.723C135.627 113.301 135.689 113.956 136.044 114.508L141.425 119.781C141.068 121.102 141.404 122.572 142.442 123.61L145.949 127.118H185.822C190.175 127.118 193.704 130.646 193.704 134.999V174.872L205 186.168V135.955L164.492 95.4266C158.763 91.6864 152.104 89.7092 145.236 89.7092Z" fill="url(#paint10_linear_4111_515)"/>
<path d="M153.562 111.378C151.008 109.737 148.047 108.87 145 108.87C141.953 108.87 138.992 109.737 136.438 111.377C135.465 112.003 135.183 113.299 135.808 114.273C136.433 115.246 137.73 115.528 138.703 114.903C140.58 113.697 142.757 113.06 145 113.06C147.243 113.06 149.42 113.697 151.297 114.903C151.647 115.128 152.039 115.236 152.427 115.236C153.117 115.236 153.792 114.896 154.192 114.273C154.817 113.3 154.535 112.003 153.562 111.378Z" fill="url(#paint11_linear_4111_515)"/>
<path d="M158.669 103.651C154.599 101.007 149.872 99.6099 145 99.6099C140.128 99.6099 135.401 101.007 131.331 103.651C130.083 104.461 129.729 106.13 130.539 107.377C131.35 108.625 133.018 108.98 134.266 108.169C137.46 106.094 141.172 104.998 145 104.998C148.828 104.998 152.54 106.094 155.734 108.169C156.187 108.464 156.696 108.604 157.199 108.604C158.08 108.604 158.944 108.172 159.46 107.377C160.271 106.13 159.917 104.461 158.669 103.651Z" fill="url(#paint12_linear_4111_515)"/>
<path d="M164.256 95.1913C158.528 91.4508 151.869 89.4736 145 89.4736C138.131 89.4736 131.472 91.4506 125.744 95.1911C124.221 96.1852 123.792 98.2254 124.787 99.748C125.781 101.271 127.821 101.699 129.344 100.705C133.999 97.6654 139.413 96.0588 145 96.0588C150.587 96.0588 156.001 97.6654 160.656 100.705C161.212 101.068 161.836 101.241 162.453 101.241C163.528 101.241 164.582 100.716 165.213 99.7482C166.208 98.2256 165.779 96.1854 164.256 95.1913Z" fill="url(#paint13_linear_4111_515)"/>
<path d="M145 124.532C147.182 124.532 148.951 122.763 148.951 120.581C148.951 118.399 147.182 116.63 145 116.63C142.818 116.63 141.049 118.399 141.049 120.581C141.049 122.763 142.818 124.532 145 124.532Z" fill="url(#paint14_linear_4111_515)"/>
</g>
<defs>
<filter id="filter0_d_4111_515" x="0" y="0" width="290" height="290" 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="10"/>
<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.35 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4111_515"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4111_515" result="shape"/>
</filter>
<linearGradient id="paint0_linear_4111_515" x1="145" y1="154.648" x2="145" y2="196.939" gradientUnits="userSpaceOnUse">
<stop stop-color="#62DBFB"/>
<stop offset="0.1912" stop-color="#57D5FA"/>
<stop offset="0.5232" stop-color="#3BC5F7"/>
<stop offset="0.954" stop-color="#0DABF2"/>
<stop offset="1" stop-color="#08A9F1"/>
</linearGradient>
<linearGradient id="paint1_linear_4111_515" x1="105.706" y1="177.176" x2="93.7059" y2="177.176" gradientUnits="userSpaceOnUse">
<stop stop-color="#0593FC" stop-opacity="0"/>
<stop offset="0.6831" stop-color="#0389FC" stop-opacity="0.683"/>
<stop offset="1" stop-color="#0182FC"/>
</linearGradient>
<linearGradient id="paint2_linear_4111_515" x1="145.118" y1="122.273" x2="145.118" y2="128.866" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint3_linear_4111_515" x1="145.118" y1="132.156" x2="145.118" y2="138.748" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint4_linear_4111_515" x1="145.118" y1="142.038" x2="145.118" y2="148.631" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint5_linear_4111_515" x1="112.144" y1="101.95" x2="168.144" y2="201.715" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint6_linear_4111_515" x1="145" y1="67.5915" x2="145" y2="137.895" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint7_linear_4111_515" x1="145" y1="110.944" x2="145" y2="105.881" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint8_linear_4111_515" x1="145" y1="121.061" x2="145" y2="115.998" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint9_linear_4111_515" x1="126.473" y1="129.525" x2="115.65" y2="108.113" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint10_linear_4111_515" x1="175.367" y1="132.235" x2="141.72" y2="85.8824" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint11_linear_4111_515" x1="143.315" y1="108.32" x2="146.188" y2="116.541" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint12_linear_4111_515" x1="142.584" y1="97.1318" x2="145.857" y2="109.025" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint13_linear_4111_515" x1="142.471" y1="88.6965" x2="145.983" y2="101.547" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<linearGradient id="paint14_linear_4111_515" x1="141.169" y1="116.749" x2="147.514" y2="123.095" gradientUnits="userSpaceOnUse">
<stop stop-color="#AEFFD1"/>
<stop offset="0.1201" stop-color="#A3F9CB"/>
<stop offset="0.3288" stop-color="#87EAB9"/>
<stop offset="0.6012" stop-color="#59D19D"/>
<stop offset="0.9235" stop-color="#19AF77"/>
<stop offset="1" stop-color="#09A76D"/>
</linearGradient>
<clipPath id="clip0_4111_515">
<rect width="104.88" height="81.9651" fill="white" transform="translate(92.5908 122.838)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,3 @@
<svg width="13" height="23" viewBox="0 0 13 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.95088 0L0.141105 11.2883H4.3742L0 23L11.5706 9.17177H7.47851L12.8404 0H3.95088Z" fill="#F7CF52"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

View File

@ -0,0 +1,43 @@
<svg width="37" height="40" viewBox="0 0 37 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M29.7686 39.9196H7.39439C6.50537 39.9196 5.78473 39.1989 5.78473 38.3099V28.9739L18.5413 29.0544L31.3783 28.9739L31.4588 30.1006V38.3904C31.4588 38.5295 31.4411 38.6645 31.4079 38.7933C31.2291 39.4873 30.5185 39.9196 29.7686 39.9196Z" fill="#8D9CA8"/>
<path d="M31.4588 30.1006V28.8933L18.6217 28.6921L5.70422 28.8933V38.3903C5.70422 39.2793 6.42487 40 7.31388 40H29.8491C30.5989 40 31.227 39.4866 31.406 38.7927H7.7163C7.27179 38.7927 6.91147 38.4324 6.91147 37.9879V30.9054C6.91147 30.4609 7.27179 30.1006 7.7163 30.1006H31.4588Z" fill="#7A8C98"/>
<path d="M16.0865 36.7002H15.4426C14.9981 36.7002 14.6378 36.3399 14.6378 35.8954V28.9739H16.8913L16.9718 30.1006V35.5735L16.8913 35.8954C16.8913 36.3399 16.531 36.7002 16.0865 36.7002Z" fill="#CCF49F"/>
<path d="M10.4527 36.7002H9.80886C9.36435 36.7002 9.00403 36.3399 9.00403 35.8954V28.9739H11.2575L11.338 30.1006V35.5735L11.2575 35.8954C11.2575 36.3399 10.8972 36.7002 10.4527 36.7002Z" fill="#CCF49F"/>
<path d="M21.7203 36.7002H21.0764C20.6319 36.7002 20.2716 36.3399 20.2716 35.8954V28.9739H22.5251L22.6056 30.1006V35.5735L22.5251 35.8954C22.5251 36.3399 22.1648 36.7002 21.7203 36.7002Z" fill="#CCF49F"/>
<path d="M27.3541 36.7002H26.7102C26.2657 36.7002 25.9054 36.3399 25.9054 35.8954V28.9739H28.1589L28.2394 30.1006V35.5735L28.1589 35.8954C28.1589 36.3399 27.7986 36.7002 27.3541 36.7002Z" fill="#CCF49F"/>
<path d="M16.9718 30.1005V28.8933L15.7646 28.6519L14.5573 28.8933V35.9758C14.5573 36.4203 14.9176 36.7806 15.3621 36.7806H16.167C16.6115 36.7806 16.9718 36.4203 16.9718 35.9758V35.5734H16.006C15.8726 35.5734 15.7646 35.4653 15.7646 35.3319V30.342C15.7646 30.2086 15.8726 30.1005 16.006 30.1005H16.9718Z" fill="#B3E59F"/>
<path d="M11.338 30.1005V28.8933L10.1308 28.6519L8.92352 28.8933V35.9758C8.92352 36.4203 9.28384 36.7806 9.72835 36.7806H10.5332C10.9777 36.7806 11.338 36.4203 11.338 35.9758V35.5734H10.3722C10.2389 35.5734 10.1308 35.4653 10.1308 35.3319V30.342C10.1308 30.2086 10.2389 30.1005 10.3722 30.1005H11.338Z" fill="#B3E59F"/>
<path d="M22.6056 30.1005V28.8933L21.3984 28.6519L20.1912 28.8933V35.9758C20.1912 36.4203 20.5515 36.7806 20.996 36.7806H21.8008C22.2453 36.7806 22.6056 36.4203 22.6056 35.9758V35.5734H21.6399C21.5065 35.5734 21.3984 35.4653 21.3984 35.3319V30.342C21.3984 30.2086 21.5065 30.1005 21.6399 30.1005H22.6056Z" fill="#B3E59F"/>
<path d="M28.2394 30.1005V28.8933L27.0322 28.6519L25.825 28.8933V35.9758C25.825 36.4203 26.1853 36.7806 26.6298 36.7806H27.4346C27.8791 36.7806 28.2394 36.4203 28.2394 35.9758V35.5734H27.2736C27.1403 35.5734 27.0322 35.4653 27.0322 35.3319V30.342C27.0322 30.2086 27.1403 30.1005 27.2736 30.1005H28.2394Z" fill="#B3E59F"/>
<path d="M28.2394 31.3079H9.32592L9.00399 31.3883C8.55948 31.3883 8.19916 31.7487 8.19916 32.1932V32.837C8.19916 33.2815 8.55948 33.6419 9.00399 33.6419H28.1589C28.6034 33.6419 28.9637 33.2815 28.9637 32.837L29.0442 32.5151V32.1127C29.0442 31.6682 28.6839 31.3079 28.2394 31.3079Z" fill="#B6C4CF"/>
<path d="M9.56741 32.5151C9.43405 32.5151 9.32596 32.407 9.32596 32.2737V31.3079H8.92354C8.47904 31.3079 8.11871 31.6682 8.11871 32.1127V32.9175C8.11871 33.362 8.47904 33.7223 8.92354 33.7223H28.2394C28.6839 33.7223 29.0443 33.362 29.0443 32.9175V32.5151H9.56741Z" fill="#9FACBA"/>
<path d="M33.7123 28.8129H3.37024C2.03672 28.8129 0.95575 27.7319 0.95575 26.3984V2.49497C0.95575 1.60145 1.36066 0.740765 2.08219 0.323219C2.43736 0.117666 2.84983 0 3.28975 0H33.7928C35.1263 0 36.2073 1.08097 36.2073 2.41449V26.4789C36.2073 26.9188 36.0896 27.3313 35.884 27.6864C35.4665 28.408 34.6058 28.8129 33.7123 28.8129Z" fill="#B6C4CF"/>
<path d="M3.48498 27.6861C2.71042 27.6861 2.08249 27.0581 2.08249 26.2836V0.32373C1.36104 0.741276 0.875244 1.52091 0.875244 2.41443V26.4788C0.875244 27.8123 1.95621 28.8933 3.28973 28.8933H33.7928C34.6863 28.8933 35.4659 28.4075 35.8835 27.6861H3.48498Z" fill="#9FACBA"/>
<path d="M32.9075 26.3983H4.17507C3.73056 26.3983 3.37024 26.038 3.37024 25.5935V3.29974C3.37024 2.85523 3.73056 2.49491 4.17507 2.49491L4.497 2.41443H32.9879C33.4325 2.41443 33.7928 2.77475 33.7928 3.21926V25.2716L33.7123 25.5935C33.7123 26.038 33.352 26.3983 32.9075 26.3983Z" fill="#F8F7F7"/>
<path d="M4.89939 25.2716C4.67718 25.2716 4.49698 25.0914 4.49698 24.8692V2.41443H4.09456C3.65006 2.41443 3.28973 2.77475 3.28973 3.21926V25.674C3.28973 26.1185 3.65006 26.4788 4.09456 26.4788H32.9879C33.4324 26.4788 33.7928 26.1185 33.7928 25.674V25.2716H4.89939Z" fill="#E8E8E8"/>
<path d="M29.4467 17.7062H7.71634C7.04962 17.7062 6.50909 17.1657 6.50909 16.4989V13.2796C6.50909 12.6129 7.04962 12.0724 7.71634 12.0724H29.4467C30.1134 12.0724 30.654 12.6129 30.654 13.2796V16.4989C30.654 17.1657 30.1134 17.7062 29.4467 17.7062Z" fill="#B6C4CF"/>
<path d="M29.4467 11.4689H7.71632C6.71777 11.4689 5.90546 12.2812 5.90546 13.2797V16.4991C5.90546 17.4976 6.71777 18.3099 7.71632 18.3099H29.4467C30.4453 18.3099 31.2576 17.4976 31.2576 16.4991V13.2797C31.2576 12.2812 30.4453 11.4689 29.4467 11.4689ZM17.3743 12.6761H19.7888C20.1221 12.6761 20.3924 12.9464 20.3924 13.2797V16.4991C20.3924 16.8324 20.1221 17.1027 19.7888 17.1027H17.3743C17.0409 17.1027 16.7706 16.8324 16.7706 16.4991V13.2797C16.7706 12.9464 17.0409 12.6761 17.3743 12.6761ZM14.9598 17.1027H12.5453C12.2119 17.1027 11.9417 16.8324 11.9417 16.4991V13.2797C11.9417 12.9464 12.2119 12.6761 12.5453 12.6761H14.9598C15.2931 12.6761 15.5634 12.9464 15.5634 13.2797V16.4991C15.5634 16.8324 15.2931 17.1027 14.9598 17.1027ZM22.2032 12.6761H24.6177C24.9511 12.6761 25.2214 12.9464 25.2214 13.2797V16.4991C25.2214 16.8324 24.9511 17.1027 24.6177 17.1027H22.2032C21.8699 17.1027 21.5996 16.8324 21.5996 16.4991V13.2797C21.5996 12.9464 21.8699 12.6761 22.2032 12.6761ZM7.1127 16.4991V13.2797C7.1127 12.9464 7.38296 12.6761 7.71632 12.6761H10.1308C10.4642 12.6761 10.7344 12.9464 10.7344 13.2797V16.4991C10.7344 16.8324 10.4642 17.1027 10.1308 17.1027H7.71632C7.38296 17.1027 7.1127 16.8324 7.1127 16.4991ZM30.0503 16.4991C30.0503 16.8324 29.7801 17.1027 29.4467 17.1027H27.0322C26.6989 17.1027 26.4286 16.8324 26.4286 16.4991V13.2797C26.4286 12.9464 26.6989 12.6761 27.0322 12.6761H29.4467C29.7801 12.6761 30.0503 12.9464 30.0503 13.2797V16.4991Z" fill="#9FACBA"/>
<path d="M14.5573 10.2616H12.9477C12.6143 10.2616 12.3441 9.9913 12.3441 9.65794C12.3441 9.32458 12.6143 9.05432 12.9477 9.05432H14.5573C14.8907 9.05432 15.161 9.32458 15.161 9.65794C15.161 9.9913 14.8907 10.2616 14.5573 10.2616Z" fill="#E8E8E8"/>
<path d="M19.3863 10.2616H17.7767C17.4433 10.2616 17.173 9.9913 17.173 9.65794C17.173 9.32458 17.4433 9.05432 17.7767 9.05432H19.3863C19.7197 9.05432 19.9899 9.32458 19.9899 9.65794C19.9899 9.9913 19.7197 10.2616 19.3863 10.2616Z" fill="#E8E8E8"/>
<path d="M24.2153 10.2616H22.6056C22.2723 10.2616 22.002 9.9913 22.002 9.65794C22.002 9.32458 22.2723 9.05432 22.6056 9.05432H24.2153C24.5487 9.05432 24.8189 9.32458 24.8189 9.65794C24.8189 9.9913 24.5487 10.2616 24.2153 10.2616Z" fill="#E8E8E8"/>
<path d="M29.0443 10.2616H27.4346C27.1013 10.2616 26.831 9.9913 26.831 9.65794C26.831 9.32458 27.1013 9.05432 27.4346 9.05432H29.0443C29.3776 9.05432 29.6479 9.32458 29.6479 9.65794C29.6479 9.9913 29.3776 10.2616 29.0443 10.2616Z" fill="#E8E8E8"/>
<path d="M9.72836 10.2616H8.1187C7.78534 10.2616 7.51508 9.9913 7.51508 9.65794C7.51508 9.32458 7.78534 9.05432 8.1187 9.05432H9.72836C10.0617 9.05432 10.332 9.32458 10.332 9.65794C10.332 9.9913 10.0617 10.2616 9.72836 10.2616Z" fill="#E8E8E8"/>
<path d="M19.7887 22.1328C19.7887 21.4661 19.2482 20.9255 18.5815 20.9255C18.4152 20.9255 18.2567 20.9592 18.1126 21.0199C17.6787 21.203 17.4547 21.6323 17.4547 22.1328C17.4547 22.7995 17.9148 23.2595 18.5815 23.2595C19.0815 23.2595 19.5106 23.036 19.6938 22.6027C19.7549 22.4583 19.7887 22.2995 19.7887 22.1328Z" fill="#DF646E"/>
<path d="M14.9597 22.1328C14.9597 21.4661 14.4192 20.9255 13.7525 20.9255C13.5862 20.9255 13.4277 20.9592 13.2836 21.0199C12.8497 21.203 12.6257 21.6323 12.6257 22.1328C12.6257 22.7995 13.0858 23.2595 13.7525 23.2595C14.2525 23.2595 14.6816 23.036 14.8648 22.6027C14.9259 22.4583 14.9597 22.2995 14.9597 22.1328Z" fill="#DF646E"/>
<path d="M10.1308 22.1328C10.1308 21.4661 9.59023 20.9255 8.92351 20.9255C8.75724 20.9255 8.59877 20.9592 8.45462 21.0199C8.02074 21.203 7.79675 21.6323 7.79675 22.1328C7.79675 22.7995 8.25679 23.2595 8.92351 23.2595C9.42355 23.2595 9.85261 23.036 10.0359 22.6027C10.097 22.4583 10.1308 22.2995 10.1308 22.1328Z" fill="#DF646E"/>
<path d="M24.6177 22.1328C24.6177 21.4661 24.0772 20.9255 23.4105 20.9255C23.2442 20.9255 23.0857 20.9592 22.9416 21.0199C22.5077 21.203 22.2837 21.6323 22.2837 22.1328C22.2837 22.7995 22.7437 23.2595 23.4105 23.2595C23.9105 23.2595 24.3395 23.036 24.5228 22.6027C24.5839 22.4583 24.6177 22.2995 24.6177 22.1328Z" fill="#DF646E"/>
<path d="M29.4467 22.1328C29.4467 21.4661 28.9062 20.9255 28.2394 20.9255C28.0732 20.9255 27.9147 20.9592 27.7705 21.0199C27.3367 21.203 27.1127 21.6323 27.1127 22.1328C27.1127 22.7995 27.5727 23.2595 28.2394 23.2595C28.7395 23.2595 29.1685 23.036 29.3518 22.6027C29.4129 22.4583 29.4467 22.2995 29.4467 22.1328Z" fill="#DF646E"/>
<path d="M19.2254 22.6962C18.5587 22.6962 18.0181 22.1556 18.0181 21.4889C18.0181 21.3226 18.0518 21.1642 18.1126 21.02C17.6788 21.203 17.3743 21.6323 17.3743 22.1328C17.3743 22.7995 17.9148 23.34 18.5815 23.34C19.082 23.34 19.5112 23.0355 19.6943 22.6017C19.5501 22.6625 19.3917 22.6962 19.2254 22.6962Z" fill="#DC4955"/>
<path d="M14.3964 22.6962C13.7297 22.6962 13.1892 22.1556 13.1892 21.4889C13.1892 21.3226 13.2228 21.1642 13.2836 21.02C12.8498 21.203 12.5453 21.6323 12.5453 22.1328C12.5453 22.7995 13.0858 23.34 13.7525 23.34C14.253 23.34 14.6823 23.0355 14.8653 22.6017C14.7211 22.6625 14.5627 22.6962 14.3964 22.6962Z" fill="#DC4955"/>
<path d="M9.56742 22.6962C8.90069 22.6962 8.36017 22.1556 8.36017 21.4889C8.36017 21.3226 8.39381 21.1642 8.45466 21.02C8.02086 21.203 7.71631 21.6323 7.71631 22.1328C7.71631 22.7995 8.25683 23.34 8.92355 23.34C9.42399 23.34 9.85329 23.0355 10.0363 22.6017C9.89216 22.6625 9.73369 22.6962 9.56742 22.6962Z" fill="#DC4955"/>
<path d="M24.0544 22.6962C23.3876 22.6962 22.8471 22.1556 22.8471 21.4889C22.8471 21.3226 22.8808 21.1642 22.9416 21.02C22.5078 21.203 22.2032 21.6323 22.2032 22.1328C22.2032 22.7995 22.7438 23.34 23.4105 23.34C23.9109 23.34 24.3402 23.0355 24.5232 22.6017C24.3791 22.6625 24.2206 22.6962 24.0544 22.6962Z" fill="#DC4955"/>
<path d="M28.8833 22.6962C28.2166 22.6962 27.676 22.1556 27.676 21.4889C27.676 21.3226 27.7097 21.1642 27.7705 21.02C27.3367 21.203 27.0322 21.6323 27.0322 22.1328C27.0322 22.7995 27.5727 23.34 28.2394 23.34C28.7399 23.34 29.1691 23.0355 29.3522 22.6017C29.208 22.6625 29.0495 22.6962 28.8833 22.6962Z" fill="#DC4955"/>
<path d="M19.4668 6.63986H16.006C15.6727 6.63986 15.4024 6.3696 15.4024 6.03624C15.4024 5.70288 15.6727 5.43262 16.006 5.43262H19.4668C19.8002 5.43262 20.0704 5.70288 20.0704 6.03624C20.0704 6.3696 19.8002 6.63986 19.4668 6.63986Z" fill="#E8E8E8"/>
<path d="M13.5915 6.63986H7.71629C7.38293 6.63986 7.11267 6.3696 7.11267 6.03624C7.11267 5.70288 7.38293 5.43262 7.71629 5.43262H13.5915C13.9249 5.43262 14.1952 5.70288 14.1952 6.03624C14.1952 6.3696 13.9249 6.63986 13.5915 6.63986Z" fill="#E8E8E8"/>
<path d="M30.4125 4.82898H28.4809C28.3475 4.82898 28.2394 4.93707 28.2394 5.07043V7.00202C28.2394 7.13538 28.3475 7.24347 28.4809 7.24347H30.4125C30.5458 7.24347 30.6539 7.13538 30.6539 7.00202V5.07043C30.6539 4.93707 30.5458 4.82898 30.4125 4.82898Z" fill="#B6C4CF"/>
<path d="M8.92351 15.8954C8.59015 15.8954 8.31989 15.6251 8.31989 15.2918V14.4869C8.31989 14.1536 8.59015 13.8833 8.92351 13.8833C9.25687 13.8833 9.52713 14.1536 9.52713 14.4869V15.2918C9.52713 15.6251 9.25687 15.8954 8.92351 15.8954Z" fill="#9FACBA"/>
<path d="M13.7525 15.8954C13.4191 15.8954 13.1489 15.6251 13.1489 15.2918V14.4869C13.1489 14.1536 13.4191 13.8833 13.7525 13.8833C14.0858 13.8833 14.3561 14.1536 14.3561 14.4869V15.2918C14.3561 15.6251 14.0858 15.8954 13.7525 15.8954Z" fill="#9FACBA"/>
<path d="M18.5815 15.8954C18.2481 15.8954 17.9778 15.6251 17.9778 15.2918V14.4869C17.9778 14.1536 18.2481 13.8833 18.5815 13.8833C18.9148 13.8833 19.1851 14.1536 19.1851 14.4869V15.2918C19.1851 15.6251 18.9148 15.8954 18.5815 15.8954Z" fill="#9FACBA"/>
<path d="M23.4104 15.8954C23.0771 15.8954 22.8068 15.6251 22.8068 15.2918V14.4869C22.8068 14.1536 23.0771 13.8833 23.4104 13.8833C23.7438 13.8833 24.0141 14.1536 24.0141 14.4869V15.2918C24.0141 15.6251 23.7438 15.8954 23.4104 15.8954Z" fill="#9FACBA"/>
<path d="M28.2394 15.8954C27.9061 15.8954 27.6358 15.6251 27.6358 15.2918V14.4869C27.6358 14.1536 27.9061 13.8833 28.2394 13.8833C28.5728 13.8833 28.843 14.1536 28.843 14.4869V15.2918C28.843 15.6251 28.5728 15.8954 28.2394 15.8954Z" fill="#9FACBA"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.37318 13.8499C-0.790913 10.6858 -0.79085 5.53728 2.37318 2.37312C5.53734 -0.79104 10.6858 -0.79104 13.8499 2.37312C16.5342 5.05748 16.9408 9.0498 15.0706 12.1674C15.0706 12.1674 14.9363 12.3928 15.1177 12.5741C16.1527 13.609 19.2581 16.7144 19.2581 16.7144C20.0822 17.5385 20.2784 18.6908 19.5476 19.4217L19.4217 19.5474C18.6909 20.2784 17.5385 20.0823 16.7145 19.2581C16.7145 19.2581 13.6157 16.1593 12.5828 15.1265C12.3927 14.9363 12.1674 15.0707 12.1674 15.0707C9.04987 16.9408 5.05754 16.5343 2.37318 13.8499ZM12.3516 12.3516C14.6896 10.0137 14.6896 6.20953 12.3516 3.87154C10.0136 1.53361 6.20946 1.53355 3.87154 3.87154C1.53355 6.20946 1.53355 10.0137 3.87154 12.3516C6.20953 14.6895 10.0136 14.6895 12.3516 12.3516Z" fill="#999999" fill-opacity="0.3"/>
<path d="M11.8337 7.62992C11.9425 7.62992 12.0531 7.60853 12.1598 7.56349C12.5857 7.38322 12.785 6.89176 12.6047 6.46576C11.4717 3.78817 8.37155 2.53161 5.69403 3.66465C5.26809 3.84493 5.06881 4.33639 5.24908 4.76239C5.42942 5.18839 5.92075 5.38754 6.34688 5.20734C8.1737 4.43432 10.289 5.29167 11.062 7.11849C11.1972 7.43799 11.5074 7.62992 11.8337 7.62992Z" fill="#999999" fill-opacity="0.3"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,16 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 24C8.8072 24 5.79717 22.7483 3.52439 20.4756C1.25166 18.2028 0 15.1928 0 12C0 8.8072 1.25166 5.79717 3.52444 3.52444C5.79717 1.25166 8.8072 0 12 0C15.1928 0 18.2028 1.25166 20.4756 3.52444C22.7483 5.79717 24 8.8072 24 12C24 15.1928 22.7483 18.2028 20.4756 20.4756C18.2028 22.7483 15.1928 24 12 24Z" fill="#EDF3F9"/>
<path d="M20.4756 20.4756C22.7483 18.2028 24 15.1928 24 12C24 8.8072 22.7483 5.79717 20.4756 3.52444C18.2028 1.25166 15.1928 0 12 0V24C15.1928 24 18.2028 22.7483 20.4756 20.4756Z" fill="#C2DBF2"/>
<path d="M12 22.5938C17.8508 22.5938 22.5938 17.8508 22.5938 12C22.5938 6.14923 17.8508 1.40625 12 1.40625C6.14923 1.40625 1.40625 6.14923 1.40625 12C1.40625 17.8508 6.14923 22.5938 12 22.5938Z" fill="#465A61"/>
<path d="M22.5938 12C22.5938 6.15858 17.8414 1.40625 12 1.40625V22.5938C17.8414 22.5938 22.5938 17.8414 22.5938 12Z" fill="#3B4A51"/>
<path d="M7.88953 9.29576C7.37672 10.072 7.07812 11.002 7.07812 12V12.7031H2.85938V12C2.85938 9.83717 3.61453 7.84779 4.87453 6.28076L7.88953 9.29576Z" fill="#F36A3D"/>
<path d="M21.1408 12V12.7031H16.922V12C16.922 11.002 16.6234 10.072 16.1106 9.29576L19.1256 6.28076C20.3856 7.84779 21.1408 9.83717 21.1408 12Z" fill="#66A6FF"/>
<path d="M19.1255 6.28078L16.1105 9.29578C15.2292 7.96078 13.7161 7.07812 12 7.07812V2.85938C14.8772 2.85938 17.4488 4.19578 19.1255 6.28078Z" fill="#FFDF40"/>
<path d="M12 2.85938V7.07812C10.2839 7.07812 8.77076 7.96078 7.88951 9.29578L4.87451 6.28078C6.55123 4.19578 9.12279 2.85938 12 2.85938Z" fill="#FF9F40"/>
<path d="M11.2969 8.48438H12.7031V14.8594H11.2969V8.48438Z" fill="#F36A3D"/>
<path d="M12 8.48438H12.7031V14.8594H12V8.48438Z" fill="#EC4C36"/>
<path d="M12 24C15.1066 24 17.625 21.4816 17.625 18.375C17.625 15.2684 15.1066 12.75 12 12.75C8.8934 12.75 6.375 15.2684 6.375 18.375C6.375 21.4816 8.8934 24 12 24Z" fill="#FFDF40"/>
<path d="M17.625 18.375C17.625 15.2734 15.1016 12.75 12 12.75V24C15.1016 24 17.625 21.4766 17.625 18.375Z" fill="#FFBE40"/>
<path d="M11.8818 21.5776L10.7118 20.7976L11.7983 19.1678L10.3921 17.7615L12.1182 15.1724L13.2882 15.9524L12.2017 17.5823L13.6079 18.9886L11.8818 21.5776Z" fill="#465A61"/>
<path d="M12.1182 15.1724L12 15.3496V21.4004L13.6079 18.9886L12.2017 17.5823L13.2882 15.9524L12.1182 15.1724Z" fill="#3B4A51"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,26 @@
<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.1346 0H3.09615C1.3862 0 0 1.3862 0 3.09615V19.9038C0 21.6138 1.3862 23 3.09615 23H18.1346C19.8446 23 21.2308 21.6138 21.2308 19.9038V3.09615C21.2308 1.3862 19.8446 0 18.1346 0Z" fill="#EF5350"/>
<path d="M20.6445 1.29056C17.6514 17.7494 4.1507 20.9781 0.482056 21.5556C0.760485 21.9974 1.1462 22.3615 1.60328 22.6141C2.06036 22.8666 2.57393 22.9994 3.09614 23H18.1346C18.9554 22.999 19.7424 22.6725 20.3228 22.0921C20.9032 21.5116 21.2298 20.7247 21.2308 19.9038V3.09615C21.2306 2.44752 21.0254 1.81554 20.6445 1.29056Z" fill="#E53935"/>
<path d="M18.1347 1.76923H3.09621C2.36337 1.76923 1.76929 2.36331 1.76929 3.09615V12.8269C1.76929 13.5598 2.36337 14.1538 3.09621 14.1538H18.1347C18.8675 14.1538 19.4616 13.5598 19.4616 12.8269V3.09615C19.4616 2.36331 18.8675 1.76923 18.1347 1.76923Z" fill="#BBDEFB"/>
<path d="M16.5513 12.3846C16.8258 11.4606 16.8808 10.4852 16.7119 9.53621C16.543 8.58718 16.1549 7.69068 15.5785 6.91809C15.0021 6.14549 14.2532 5.51814 13.3916 5.08598C12.53 4.65381 11.5793 4.42877 10.6154 4.42877C9.65145 4.42877 8.70082 4.65381 7.83918 5.08598C6.97755 5.51814 6.2287 6.14549 5.65227 6.91809C5.07583 7.69068 4.68773 8.58718 4.51885 9.53621C4.34997 10.4852 4.40498 11.4606 4.67951 12.3846L2.875 12.1635V2.875H18.3558V12.1635L16.5513 12.3846Z" fill="#90CAF9"/>
<path d="M10.6154 5.30769C10.5573 5.30772 10.4998 5.2963 10.4461 5.27408C10.3924 5.25187 10.3436 5.21929 10.3026 5.17821C10.2615 5.13713 10.2289 5.08836 10.2067 5.03468C10.1845 4.981 10.1731 4.92347 10.1731 4.86538V3.09615C10.1731 2.97884 10.2197 2.86634 10.3026 2.78339C10.3856 2.70044 10.4981 2.65384 10.6154 2.65384C10.7327 2.65384 10.8452 2.70044 10.9282 2.78339C11.0111 2.86634 11.0577 2.97884 11.0577 3.09615V4.86538C11.0577 4.92347 11.0463 4.981 11.0241 5.03468C11.0019 5.08836 10.9693 5.13713 10.9282 5.17821C10.8872 5.21929 10.8384 5.25187 10.7847 5.27408C10.731 5.2963 10.6735 5.30772 10.6154 5.30769Z" fill="#37474F"/>
<path d="M6.54954 6.99182C6.49145 6.99189 6.43392 6.98047 6.38026 6.95823C6.32659 6.93599 6.27785 6.90336 6.23683 6.86223L4.995 5.62039C4.9133 5.5372 4.86776 5.42511 4.86829 5.30851C4.86882 5.19191 4.91537 5.08024 4.99782 4.99779C5.08027 4.91534 5.19194 4.86879 5.30854 4.86826C5.42514 4.86773 5.53723 4.91327 5.62043 4.99497L6.86226 6.2368C6.9241 6.29866 6.96621 6.37746 6.98327 6.46325C7.00032 6.54904 6.99156 6.63796 6.9581 6.71877C6.92463 6.79958 6.86795 6.86865 6.79523 6.91725C6.72251 6.96585 6.63701 6.9918 6.54954 6.99182Z" fill="#37474F"/>
<path d="M14.6812 6.99184C14.5938 6.99182 14.5083 6.96587 14.4355 6.91727C14.3628 6.86867 14.3061 6.79959 14.2727 6.71878C14.2392 6.63797 14.2304 6.54906 14.2475 6.46327C14.2646 6.37748 14.3067 6.29868 14.3685 6.23682L15.6103 4.99499C15.6513 4.95331 15.7001 4.92015 15.7539 4.89743C15.8077 4.87471 15.8655 4.86288 15.9239 4.86261C15.9823 4.86235 16.0402 4.87366 16.0942 4.89589C16.1482 4.91812 16.1973 4.95084 16.2386 4.99214C16.2799 5.03345 16.3126 5.08253 16.3349 5.13655C16.3571 5.19057 16.3684 5.24846 16.3681 5.30687C16.3679 5.36529 16.356 5.42307 16.3333 5.47689C16.3106 5.5307 16.2774 5.57948 16.2358 5.62041L14.9939 6.86224C14.9529 6.90338 14.9042 6.93601 14.8505 6.95825C14.7969 6.98049 14.7393 6.99191 14.6812 6.99184Z" fill="#37474F"/>
<path d="M10.6154 11.0577C10.5573 11.0578 10.4997 11.0463 10.4461 11.0241C10.3924 11.0019 10.3437 10.9692 10.3026 10.9281L7.48769 8.11314C7.40475 8.0302 7.35815 7.91771 7.35815 7.80041C7.35815 7.68312 7.40475 7.57063 7.48769 7.48769C7.57063 7.40475 7.68312 7.35815 7.80041 7.35815C7.91771 7.35815 8.0302 7.40475 8.11314 7.48769L10.9281 10.3027C10.9899 10.3645 11.032 10.4433 11.0491 10.5291C11.0661 10.6149 11.0574 10.7038 11.0239 10.7846C10.9904 10.8654 10.9338 10.9345 10.861 10.9831C10.7883 11.0317 10.7028 11.0577 10.6154 11.0577Z" fill="#37474F"/>
<path d="M3.98083 19.9039C5.20222 19.9039 6.19236 18.9137 6.19236 17.6923C6.19236 16.4709 5.20222 15.4808 3.98083 15.4808C2.75943 15.4808 1.76929 16.4709 1.76929 17.6923C1.76929 18.9137 2.75943 19.9039 3.98083 19.9039Z" fill="#CFD8DC"/>
<path d="M5.7035 16.3228C5.78399 16.7463 5.75972 17.1831 5.6328 17.5952C5.50588 18.0072 5.28016 18.382 4.9753 18.6868C4.67043 18.9917 4.29567 19.2174 3.88363 19.3443C3.47159 19.4713 3.03477 19.4955 2.61121 19.415C2.9987 19.7293 3.48188 19.9017 3.98075 19.9038C4.56708 19.9032 5.12919 19.6699 5.54379 19.2553C5.95838 18.8407 6.1916 18.2786 6.19229 17.6923C6.19015 17.1934 6.0177 16.7103 5.7035 16.3228Z" fill="#B0BEC5"/>
<path d="M17.25 19.9039C18.4714 19.9039 19.4615 18.9137 19.4615 17.6923C19.4615 16.4709 18.4714 15.4808 17.25 15.4808C16.0286 15.4808 15.0385 16.4709 15.0385 17.6923C15.0385 18.9137 16.0286 19.9039 17.25 19.9039Z" fill="#CFD8DC"/>
<path d="M18.9728 16.3228C19.0533 16.7463 19.029 17.1831 18.9021 17.5952C18.7752 18.0072 18.5495 18.382 18.2446 18.6868C17.9397 18.9917 17.565 19.2174 17.1529 19.3443C16.7409 19.4713 16.3041 19.4955 15.8805 19.415C16.268 19.7293 16.7512 19.9017 17.25 19.9038C17.8364 19.9032 18.3985 19.6699 18.8131 19.2553C19.2277 18.8407 19.4609 18.2786 19.4616 17.6923C19.4594 17.1934 19.287 16.7103 18.9728 16.3228Z" fill="#B0BEC5"/>
<path d="M4.42312 17.6923C4.42277 17.8095 4.37606 17.9218 4.29319 18.0047C4.21032 18.0876 4.09802 18.1343 3.98082 18.1346H1.81351C1.75455 17.8427 1.75455 17.5419 1.81351 17.25H3.98082C4.09802 17.2504 4.21032 17.2971 4.29319 17.3799C4.37606 17.4628 4.42277 17.5751 4.42312 17.6923Z" fill="#546E7A"/>
<path d="M19.0989 16.4716L17.5641 18.0064C17.4802 18.0886 17.3675 18.1346 17.25 18.1346C17.1326 18.1346 17.0199 18.0886 16.936 18.0064C16.8531 17.9228 16.8066 17.81 16.8066 17.6923C16.8066 17.5747 16.8531 17.4618 16.936 17.3783L18.4708 15.8435C18.7181 16.0111 18.9312 16.2243 19.0989 16.4716Z" fill="#546E7A"/>
<path d="M15.4808 21.6731H5.75005C5.63274 21.6731 5.52024 21.6265 5.43729 21.5435C5.35434 21.4606 5.30774 21.3481 5.30774 21.2308C5.30774 21.1135 5.35434 21.0009 5.43729 20.918C5.52024 20.8351 5.63274 20.7885 5.75005 20.7885H15.4808C15.5981 20.7885 15.7106 20.8351 15.7936 20.918C15.8765 21.0009 15.9231 21.1135 15.9231 21.2308C15.9231 21.3481 15.8765 21.4606 15.7936 21.5435C15.7106 21.6265 15.5981 21.6731 15.4808 21.6731Z" fill="#37474F"/>
<path d="M14.1539 19.9038H7.07695C6.95964 19.9038 6.84714 19.8572 6.76419 19.7743C6.68124 19.6913 6.63464 19.5788 6.63464 19.4615C6.63464 19.3442 6.68124 19.2317 6.76419 19.1488C6.84714 19.0658 6.95964 19.0192 7.07695 19.0192H14.1539C14.2712 19.0192 14.3837 19.0658 14.4666 19.1488C14.5496 19.2317 14.5962 19.3442 14.5962 19.4615C14.5962 19.5788 14.5496 19.6913 14.4666 19.7743C14.3837 19.8572 14.2712 19.9038 14.1539 19.9038Z" fill="#37474F"/>
<path d="M14.1539 16.3654H7.07695C6.95964 16.3654 6.84714 16.3188 6.76419 16.2358C6.68124 16.1529 6.63464 16.0404 6.63464 15.9231C6.63464 15.8058 6.68124 15.6933 6.76419 15.6103C6.84714 15.5274 6.95964 15.4808 7.07695 15.4808H14.1539C14.2712 15.4808 14.3837 15.5274 14.4666 15.6103C14.5496 15.6933 14.5962 15.8058 14.5962 15.9231C14.5962 16.0404 14.5496 16.1529 14.4666 16.2358C14.3837 16.3188 14.2712 16.3654 14.1539 16.3654Z" fill="#37474F"/>
<path d="M18.1347 1.76923H3.09621C2.74441 1.76961 2.40712 1.90953 2.15836 2.1583C1.90959 2.40706 1.76967 2.74435 1.76929 3.09615V12.8269C1.76967 13.1787 1.90959 13.516 2.15836 13.7648C2.40712 14.0135 2.74441 14.1535 3.09621 14.1538H18.1347C18.4865 14.1535 18.8238 14.0135 19.0725 13.7648C19.3213 13.516 19.4612 13.1787 19.4616 12.8269V3.09615C19.4612 2.74435 19.3213 2.40706 19.0725 2.1583C18.8238 1.90953 18.4865 1.76961 18.1347 1.76923ZM17.2501 11.0577H13.7116C13.6535 11.0577 13.596 11.0463 13.5423 11.0241C13.4886 11.0019 13.4398 10.9693 13.3988 10.9282C13.3577 10.8871 13.3251 10.8384 13.3029 10.7847C13.2807 10.731 13.2693 10.6735 13.2693 10.6154C13.2693 9.91154 12.9897 9.23652 12.492 8.73883C11.9943 8.24113 11.3193 7.96153 10.6154 7.96153C9.9116 7.96153 9.23658 8.24113 8.73889 8.73883C8.2412 9.23652 7.9616 9.91154 7.9616 10.6154C7.96163 10.6735 7.95021 10.731 7.92799 10.7847C7.90578 10.8384 7.8732 10.8871 7.83212 10.9282C7.79104 10.9693 7.74227 11.0019 7.68859 11.0241C7.63491 11.0463 7.57738 11.0577 7.51929 11.0577H3.98083C3.92273 11.0577 3.8652 11.0463 3.81152 11.0241C3.75784 11.0019 3.70907 10.9693 3.66799 10.9282C3.62691 10.8871 3.59434 10.8384 3.57212 10.7847C3.5499 10.731 3.53848 10.6735 3.53852 10.6154C3.53852 8.73846 4.28412 6.93842 5.6113 5.61124C6.93848 4.28406 8.73852 3.53846 10.6154 3.53846C12.4924 3.53846 14.2924 4.28406 15.6196 5.61124C16.9468 6.93842 17.6924 8.73846 17.6924 10.6154C17.6924 10.6735 17.681 10.731 17.6588 10.7847C17.6365 10.8384 17.604 10.8871 17.5629 10.9282C17.5218 10.9693 17.473 11.0019 17.4194 11.0241C17.3657 11.0463 17.3082 11.0577 17.2501 11.0577Z" fill="#FFEE58"/>
<path d="M18.1347 1.76923H18.1031C17.4341 11.9799 5.19342 12.4807 1.76929 12.4194V12.8269C1.76967 13.1787 1.90959 13.516 2.15836 13.7648C2.40712 14.0135 2.74441 14.1535 3.09621 14.1538H18.1347C18.4865 14.1535 18.8238 14.0135 19.0725 13.7648C19.3213 13.516 19.4612 13.1787 19.4616 12.8269V3.09615C19.4612 2.74435 19.3213 2.40706 19.0725 2.1583C18.8238 1.90953 18.4865 1.76961 18.1347 1.76923Z" fill="#90CAF9"/>
<path d="M18.1347 1.76923H18.1031C18.0218 3.53365 17.4778 5.24565 16.5259 6.7335C17.2874 7.88491 17.693 9.23498 17.6924 10.6154C17.6924 10.6735 17.681 10.731 17.6588 10.7847C17.6365 10.8384 17.604 10.8871 17.5629 10.9282C17.5218 10.9693 17.473 11.0019 17.4194 11.0241C17.3657 11.0463 17.3082 11.0577 17.2501 11.0577H13.7116C13.6535 11.0577 13.596 11.0463 13.5423 11.0241C13.4886 11.0019 13.4398 10.9693 13.3988 10.9282C13.3577 10.8871 13.3251 10.8384 13.3029 10.7847C13.2807 10.731 13.2693 10.6735 13.2693 10.6154C13.2688 10.3667 13.2332 10.1193 13.1635 9.88054C9.14984 12.2871 3.84304 12.4565 1.76929 12.4194V12.8269C1.76967 13.1787 1.90959 13.516 2.15836 13.7648C2.40712 14.0135 2.74441 14.1535 3.09621 14.1538H18.1347C18.4865 14.1535 18.8238 14.0135 19.0725 13.7648C19.3213 13.516 19.4612 13.1787 19.4616 12.8269V3.09615C19.4612 2.74435 19.3213 2.40706 19.0725 2.1583C18.8238 1.90953 18.4865 1.76961 18.1347 1.76923Z" fill="#FDD835"/>
<path d="M10.6154 12.3846C11.5925 12.3846 12.3847 11.5925 12.3847 10.6154C12.3847 9.63827 11.5925 8.84616 10.6154 8.84616C9.6383 8.84616 8.84619 9.63827 8.84619 10.6154C8.84619 11.5925 9.6383 12.3846 10.6154 12.3846Z" fill="#CFD8DC"/>
<path d="M11.9109 9.41928C11.9288 9.52222 11.9393 9.62632 11.9423 9.73076C11.9418 10.3171 11.7086 10.8793 11.2939 11.2939C10.8793 11.7085 10.3172 11.9417 9.73079 11.9423C9.62635 11.9393 9.52225 11.9288 9.41931 11.9108C9.75346 12.2224 10.1955 12.392 10.6523 12.3841C11.1091 12.3761 11.545 12.191 11.868 11.868C12.1911 11.5449 12.3761 11.1091 12.3841 10.6523C12.3921 10.1955 12.2224 9.75343 11.9109 9.41928Z" fill="#B0BEC5"/>
<path d="M3.53842 4.86538C4.02698 4.86538 4.42304 4.37031 4.42304 3.75961C4.42304 3.14891 4.02698 2.65384 3.53842 2.65384C3.04986 2.65384 2.65381 3.14891 2.65381 3.75961C2.65381 4.37031 3.04986 4.86538 3.53842 4.86538Z" fill="white"/>
<path d="M3.09612 6.63462C3.3404 6.63462 3.53842 6.43659 3.53842 6.19231C3.53842 5.94803 3.3404 5.75 3.09612 5.75C2.85184 5.75 2.65381 5.94803 2.65381 6.19231C2.65381 6.43659 2.85184 6.63462 3.09612 6.63462Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,41 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.998 2.5882C11.8004 2.5882 11.6403 2.42817 11.6403 2.23069V0.357516C11.6403 0.160078 11.8004 0 11.998 0C12.1956 0 12.3558 0.160031 12.3558 0.357516V2.23073C12.3558 2.42817 12.1956 2.5882 11.998 2.5882Z" fill="#E6E2E6"/>
<path d="M5.22457 2.5882C5.02699 2.5882 4.86682 2.42817 4.86682 2.23069V0.357516C4.86682 0.160078 5.02699 0 5.22457 0C5.42215 0 5.58232 0.160031 5.58232 0.357516V2.23073C5.58232 2.42817 5.42215 2.5882 5.22457 2.5882Z" fill="#E6E2E6"/>
<path d="M18.7714 2.5882C18.5738 2.5882 18.4137 2.42817 18.4137 2.23069V0.357516C18.4137 0.160078 18.5739 0 18.7714 0C18.969 0 19.1292 0.160031 19.1292 0.357516V2.23073C19.1292 2.42817 18.969 2.5882 18.7714 2.5882Z" fill="#E6E2E6"/>
<path d="M17.6937 1.7467H19.8492C20.0782 1.7467 20.2814 1.8937 20.3528 2.1112L20.7326 3.26672C20.7832 3.42084 20.6683 3.57942 20.506 3.57942H17.0369C16.8746 3.57942 16.7596 3.42084 16.8103 3.26672L17.19 2.1112C17.2615 1.8937 17.4647 1.7467 17.6937 1.7467Z" fill="#545454"/>
<path d="M17.6935 3.57938H19.8492C20.0782 3.57938 20.2814 3.72638 20.3528 3.94383L20.7326 5.0993C20.7832 5.25342 20.6683 5.412 20.506 5.412H17.0369C16.8746 5.412 16.7596 5.25342 16.8103 5.0993L17.1901 3.94359C17.2615 3.72628 17.4646 3.57938 17.6935 3.57938Z" fill="#545454"/>
<path d="M17.6935 5.41205H19.8492C20.0782 5.41205 20.2814 5.55905 20.3528 5.77655L20.7326 6.93206C20.7832 7.08619 20.6683 7.24477 20.506 7.24477H17.0369C16.8746 7.24477 16.7596 7.08619 16.8103 6.93206L17.1901 5.77636C17.2615 5.55895 17.4646 5.41205 17.6935 5.41205Z" fill="#545454"/>
<path d="M13.0759 1.7467H10.9203C10.6912 1.7467 10.488 1.8937 10.4166 2.1112L10.0369 3.26672C9.9862 3.42084 10.1011 3.57942 10.2635 3.57942H13.7325C13.8949 3.57942 14.0098 3.42084 13.9591 3.26672L13.5793 2.11102C13.5079 1.89361 13.3049 1.7467 13.0759 1.7467Z" fill="#545454"/>
<path d="M13.0757 3.57938H10.9203C10.6912 3.57938 10.4881 3.72638 10.4166 3.94383L10.0369 5.0993C9.9862 5.25342 10.1011 5.412 10.2635 5.412H13.7325C13.8949 5.412 14.0098 5.25342 13.9591 5.0993L13.5794 3.94378C13.508 3.72638 13.3048 3.57938 13.0757 3.57938Z" fill="#545454"/>
<path d="M13.0759 5.41205H10.9203C10.6912 5.41205 10.4881 5.55905 10.4166 5.77655L10.0369 6.93206C9.9862 7.08619 10.1011 7.24477 10.2635 7.24477H13.7325C13.8949 7.24477 14.0098 7.08619 13.9591 6.93206L13.5793 5.77636C13.5079 5.55895 13.3049 5.41205 13.0759 5.41205Z" fill="#545454"/>
<path d="M6.30253 1.7467H4.14689C3.91781 1.7467 3.71465 1.8937 3.64321 2.1112L3.26343 3.26667C3.21276 3.4208 3.3277 3.57938 3.49003 3.57938H6.9591C7.12143 3.57938 7.23637 3.4208 7.1857 3.26667L6.80592 2.11097C6.73448 1.89361 6.53146 1.7467 6.30253 1.7467Z" fill="#545454"/>
<path d="M3.44264 2.72137L3.26343 3.26667C3.21276 3.4208 3.3277 3.57937 3.49003 3.57937H6.9591C7.12143 3.57937 7.23637 3.4208 7.1857 3.26667L7.0065 2.72137H3.44264Z" fill="#494949"/>
<path d="M6.30248 3.57938H4.14684C3.91776 3.57938 3.71461 3.72638 3.64317 3.94383L3.26343 5.0993C3.21276 5.25342 3.3277 5.412 3.49003 5.412H6.95911C7.12143 5.412 7.23637 5.25342 7.1857 5.0993L6.80592 3.94359C6.73443 3.72628 6.53142 3.57938 6.30248 3.57938Z" fill="#545454"/>
<path d="M3.44264 4.55405L3.26343 5.09934C3.21276 5.25347 3.3277 5.41205 3.49003 5.41205H6.9591C7.12143 5.41205 7.23637 5.25347 7.1857 5.09934L7.0065 4.55405H3.44264Z" fill="#494949"/>
<path d="M6.30225 5.41205H4.14684C3.91776 5.41205 3.71461 5.55905 3.64317 5.77655L3.26343 6.93206C3.21276 7.08619 3.3277 7.24477 3.49003 7.24477H6.95911C7.12143 7.24477 7.23637 7.08619 7.1857 6.93206L6.80596 5.77655C6.73448 5.55905 6.53132 5.41205 6.30225 5.41205Z" fill="#545454"/>
<path d="M3.44264 6.38666L3.26343 6.93196C3.21276 7.08608 3.3277 7.24466 3.49003 7.24466H6.9591C7.12143 7.24466 7.23637 7.08608 7.1857 6.93196L7.0065 6.38666H3.44264Z" fill="#494949"/>
<path d="M10.2161 2.72137L10.0369 3.26667C9.9862 3.4208 10.1011 3.57937 10.2635 3.57937H13.7325C13.8949 3.57937 14.0098 3.4208 13.9591 3.26667L13.7799 2.72137H10.2161Z" fill="#494949"/>
<path d="M10.2161 4.55405L10.0369 5.09934C9.9862 5.25347 10.1011 5.41205 10.2635 5.41205H13.7325C13.8949 5.41205 14.0098 5.25347 13.9591 5.09934L13.7799 4.55405H10.2161Z" fill="#494949"/>
<path d="M10.2161 6.38666L10.0369 6.93196C9.9862 7.08608 10.1011 7.24466 10.2635 7.24466H13.7325C13.8949 7.24466 14.0098 7.08608 13.9591 6.93196L13.7799 6.38666H10.2161Z" fill="#494949"/>
<path d="M16.9895 2.72137L16.8103 3.26667C16.7596 3.4208 16.8746 3.57937 17.0369 3.57937H20.506C20.6683 3.57937 20.7832 3.4208 20.7326 3.26667L20.5534 2.72137H16.9895Z" fill="#494949"/>
<path d="M16.9895 4.55405L16.8103 5.09934C16.7596 5.25347 16.8746 5.41205 17.0369 5.41205H20.506C20.6683 5.41205 20.7832 5.25347 20.7326 5.09934L20.5534 4.55405H16.9895Z" fill="#494949"/>
<path d="M16.9895 6.38666L16.8103 6.93196C16.7596 7.08608 16.8746 7.24466 17.0369 7.24466H20.506C20.6683 7.24466 20.7832 7.08608 20.7326 6.93196L20.5534 6.38666H16.9895Z" fill="#494949"/>
<path d="M11.0522 7.24466H12.9437V8.88885H11.0522V7.24466Z" fill="#545454"/>
<path d="M4.27881 7.24466H6.17031V8.88885H4.27881V7.24466Z" fill="#545454"/>
<path d="M19.7172 8.88892H17.8257V7.24473H19.7172V8.88892Z" fill="#545454"/>
<path d="M1.21143 10.9806H22.7886V21.9083H1.21143V10.9806Z" fill="#545454"/>
<path d="M1.21143 10.9806H22.7886V11.8386H1.21143V10.9806Z" fill="#494949"/>
<path d="M11.998 12.3605C11.8004 12.3605 11.6403 12.2004 11.6403 12.003V10.7935C11.6403 10.596 11.8004 10.436 11.998 10.436C12.1956 10.436 12.3558 10.596 12.3558 10.7935V12.003C12.3558 12.2004 12.1956 12.3605 11.998 12.3605Z" fill="#E6E2E6"/>
<path d="M5.22457 12.3605C5.02699 12.3605 4.86682 12.2004 4.86682 12.003V10.7935C4.86682 10.596 5.02699 10.436 5.22457 10.436C5.42215 10.436 5.58232 10.596 5.58232 10.7935V12.003C5.58232 12.2004 5.42215 12.3605 5.22457 12.3605Z" fill="#E6E2E6"/>
<path d="M18.7714 12.3605C18.5738 12.3605 18.4137 12.2004 18.4137 12.003V10.7935C18.4137 10.596 18.5739 10.436 18.7714 10.436C18.969 10.436 19.1292 10.596 19.1292 10.7935V12.003C19.1292 12.2004 18.969 12.3605 18.7714 12.3605Z" fill="#E6E2E6"/>
<path d="M23.5233 10.9806H0.476672C0.213422 10.9806 0 10.7672 0 10.5039V9.36559C0 9.10234 0.213422 8.88892 0.476672 8.88892H23.5233C23.7865 8.88892 24 9.10234 24 9.36559V10.5039C24 10.7672 23.7866 10.9806 23.5233 10.9806Z" fill="#A8A7A8"/>
<path d="M23.5231 10.1226H0.476859C0.213516 10.1226 0 9.90929 0 9.64609V10.5041C0 10.7673 0.213516 10.9806 0.476859 10.9806H23.5231C23.7865 10.9806 24 10.7673 24 10.5041V9.64609C24 9.90929 23.7865 10.1226 23.5231 10.1226Z" fill="#818181"/>
<path d="M23.5233 24H0.476672C0.213422 24 0 23.7866 0 23.5234V22.385C0 22.1217 0.213422 21.9083 0.476672 21.9083H23.5233C23.7865 21.9083 24 22.1217 24 22.385V23.5234C24 23.7866 23.7866 24 23.5233 24Z" fill="#A8A7A8"/>
<path d="M23.5231 23.142H0.476859C0.213516 23.142 0 22.9287 0 22.6655V23.5235C0 23.7867 0.213516 24 0.476859 24H23.5231C23.7865 24 24 23.7867 24 23.5235V22.6655C24 22.9287 23.7865 23.142 23.5231 23.142Z" fill="#818181"/>
<path d="M15.6454 19.172L12.6056 14.0633C12.3317 13.6029 11.6644 13.6029 11.3904 14.0633L8.35062 19.172C8.07068 19.6425 8.4102 20.2384 8.95816 20.2384H15.0378C15.5858 20.2384 15.9253 19.6425 15.6454 19.172Z" fill="#F6E266"/>
<path d="M15.6023 19.0995C15.4767 19.2667 15.2772 19.3804 15.0379 19.3804H8.95829C8.71894 19.3804 8.51944 19.2667 8.39387 19.0995L8.35074 19.172C8.0708 19.6425 8.41032 20.2384 8.95829 20.2384H15.0379C15.5859 20.2384 15.9254 19.6425 15.6454 19.172L15.6023 19.0995Z" fill="#FFC239"/>
<path d="M11.0522 8.06677H12.9437V8.88887H11.0522V8.06677Z" fill="#494949"/>
<path d="M4.27881 8.06677H6.17031V8.88887H4.27881V8.06677Z" fill="#494949"/>
<path d="M17.8257 8.06677H19.7172V8.88887H17.8257V8.06677Z" fill="#494949"/>
<path d="M11.9225 15.9461L10.9958 17.4033C10.9256 17.5136 10.9211 17.6534 10.9841 17.7679C11.0471 17.8825 11.1675 17.9536 11.2983 17.9536H11.7902L11.2135 18.8605C11.1073 19.0275 11.1567 19.2488 11.3237 19.355C11.4658 19.449 11.7038 19.4221 11.8185 19.2448L12.7453 17.7876C12.8154 17.6773 12.8198 17.5376 12.7569 17.423C12.6939 17.3085 12.5735 17.2373 12.4427 17.2373H11.9508L12.5276 16.3304C12.6338 16.1634 12.5844 15.942 12.4173 15.8359C12.2503 15.7298 12.0287 15.7792 11.9225 15.9461Z" fill="#DD636E"/>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,8 @@
<svg width="32" height="40" viewBox="0 0 32 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M31.3558 24.3356C31.3558 32.9868 24.3366 40 15.6779 40C7.01928 40 0 32.9868 0 24.3356C0 16.6883 12.2504 3.26474 15.0936 0.252246C15.411 -0.0840819 15.945 -0.0840819 16.2623 0.252246C19.1055 3.26482 31.3558 16.6883 31.3558 24.3356Z" fill="#B3DAFE"/>
<path d="M16.2623 0.252246C15.9449 -0.0840819 15.4109 -0.0840819 15.0936 0.252246C14.9197 0.436542 14.7101 0.660292 14.4707 0.918729C18.1444 4.88583 28.9414 17.156 28.9414 24.3355C28.9414 32.5809 22.5653 39.3383 14.4707 39.9541C14.8691 39.9845 15.2717 39.9999 15.678 39.9999C24.3366 39.9999 31.3559 32.9867 31.3559 24.3355C31.3559 16.6883 19.1055 3.26482 16.2623 0.252246Z" fill="#8AC9FE"/>
<path d="M31.3146 25.4707C26.9452 23.6196 22.2099 23.9811 9.98543 26.5371C7.23286 27.1127 4.08365 27.8032 0.595215 28.6251C2.46216 35.191 8.50794 39.9999 15.678 39.9999C23.9546 39.9999 30.7324 33.5919 31.3146 25.4707Z" fill="#60B7FF"/>
<path d="M31.3146 25.4633C30.5689 25.1473 29.7422 24.8981 28.9369 24.7148C28.902 26.2409 28.6664 27.6787 28.2134 29.0619L30.1492 30.3706C30.4571 29.6496 30.7395 28.766 30.9738 27.7362C31.164 26.8995 31.2649 26.132 31.3146 25.4633Z" fill="#26A6FE"/>
<path d="M21.5314 27.7526C13.3347 26.4026 9.06084 21.1593 0.388828 21.7261C0.139062 22.6479 0 23.5245 0 24.3356C0 32.9868 7.01921 40 15.6779 40C23.2857 40 29.6271 34.5856 31.0545 27.4032C27.1755 28.2694 24.002 28.1595 21.5314 27.7526Z" fill="#0593FC"/>
<path d="M28.5442 27.8469C27.0352 34.4294 21.3767 39.4302 14.465 39.9537C14.8653 39.9844 15.2698 40 15.6779 40C23.2857 40 29.627 34.5855 31.0545 27.4032C30.182 27.598 29.3454 27.7431 28.5442 27.8469Z" fill="#0182FC"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,25 @@
<svg width="311" height="345" viewBox="0 0 311 345" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M309.392 1.11133H0.715698V344.077H309.392V1.11133Z" fill="#EBEBEC"/>
<path d="M309.392 344.817H0.715982C0.309099 344.817 0.0131836 344.484 0.0131836 344.114V1.11149C0.0131836 0.741596 0.346088 0.408691 0.715982 0.408691H309.392C309.799 0.408691 310.095 0.741596 310.095 1.11149V344.077C310.095 344.484 309.762 344.78 309.392 344.78V344.817ZM1.45577 343.374H308.689V1.85128H1.45577V343.411V343.374Z" fill="#CCCCCC"/>
<path d="M309.392 344.817H309.244C309.244 344.817 308.911 344.743 308.763 344.632L293.561 331.501L154.481 173.075C154.259 172.816 154.259 172.409 154.481 172.114L293.524 13.799L308.948 0.593798C309.17 0.408851 309.466 0.371862 309.725 0.48283C309.984 0.593798 310.132 0.852723 310.132 1.14864V344.114C310.132 344.521 309.799 344.817 309.429 344.817H309.392ZM156.034 172.631L294.633 330.502L308.726 342.672V2.70219L294.559 14.8347L156.034 172.631Z" fill="#CCCCCC"/>
<path d="M155.072 173.334C154.85 173.334 154.666 173.26 154.518 173.075L15.5115 14.7236L0.271872 1.66633C0.0129463 1.48138 -0.0610325 1.14848 0.0499357 0.889553C0.160904 0.593638 0.419829 0.408691 0.715744 0.408691H309.392C309.688 0.408691 309.947 0.593638 310.058 0.889553C310.169 1.18547 310.058 1.48138 309.836 1.66633L294.485 14.7976L155.553 173.075C155.553 173.075 155.22 173.334 154.998 173.334H155.072ZM2.67618 1.85128L16.5472 13.7249L155.072 171.522L293.524 13.7988L307.469 1.85128H2.67618Z" fill="#CCCCCC"/>
<path d="M0.715982 344.817C0.715982 344.817 0.494045 344.817 0.420067 344.743C0.161141 344.632 0.0131836 344.373 0.0131836 344.077V1.11165C0.0131836 0.852723 0.161141 0.593798 0.420067 0.48283C0.678992 0.371862 0.974907 0.408851 1.19684 0.593798L16.5474 13.725L155.627 172.15C155.849 172.409 155.849 172.816 155.627 173.112L16.5844 331.427L1.15985 344.632C1.15985 344.632 0.863939 344.817 0.678992 344.817H0.715982ZM1.45577 2.70219V342.561L15.6227 330.428L154.148 172.631L15.5117 14.7237L1.45577 2.70219Z" fill="#CCCCCC"/>
<path d="M309.281 344.817H0.71569C0.419775 344.817 0.160849 344.632 0.049881 344.336C-0.0610871 344.04 0.049881 343.744 0.271817 343.559L15.6224 330.428L154.554 172.151C154.813 171.855 155.368 171.855 155.627 172.151L294.633 330.502L309.762 343.559C309.984 343.744 310.058 344.077 309.947 344.336C309.836 344.632 309.577 344.817 309.281 344.817ZM2.67613 343.374H307.358L293.635 331.501L155.109 173.704L16.5841 331.427L2.63914 343.374H2.67613Z" fill="#CCCCCC"/>
<path d="M294.078 14.2798H16.0659V330.983H294.078V14.2798Z" fill="#B2B4B6"/>
<path d="M294.078 331.686H16.0661C15.6592 331.686 15.3633 331.353 15.3633 330.983V14.2799C15.3633 13.8731 15.6962 13.5771 16.0661 13.5771H294.078C294.485 13.5771 294.781 13.9101 294.781 14.2799V330.983C294.781 331.39 294.448 331.686 294.078 331.686ZM16.7689 330.243H293.338V14.9827H16.7689V330.243Z" fill="#CCCCCC"/>
<path d="M290.305 17.8306H19.839V325.952H290.305V17.8306Z" fill="#D8D9DA"/>
<path d="M290.305 326.655H19.8392C19.4323 326.655 19.1364 326.322 19.1364 325.952V17.8307C19.1364 17.4238 19.4693 17.1279 19.8392 17.1279H290.305C290.712 17.1279 291.008 17.4608 291.008 17.8307V325.952C291.008 326.359 290.675 326.655 290.305 326.655ZM20.5419 325.249H289.566V18.5705H20.5419V325.249Z" fill="#9E9FA0"/>
<path d="M285.645 22.269H24.3519V321.772H285.645V22.269Z" fill="white"/>
<path d="M279.985 28.3726H30.2701V315.595H279.985V28.3726Z" fill="url(#paint0_linear_4883_327)" fill-opacity="0.5"/>
<path d="M279.986 316.298H30.2704C29.8635 316.298 29.5676 315.966 29.5676 315.596V28.3732C29.5676 27.9663 29.9005 27.6704 30.2704 27.6704H279.986C280.393 27.6704 280.688 28.0033 280.688 28.3732V315.596C280.688 316.003 280.356 316.298 279.986 316.298ZM30.9732 314.856H279.246V29.076H30.9732V314.856Z" fill="#D5D7D8"/>
<defs>
<linearGradient id="paint0_linear_4883_327" x1="155.109" y1="384.21" x2="155.109" y2="-45.7172" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="0.15" stop-color="#FAFDFD"/>
<stop offset="0.31" stop-color="#ECF7F8"/>
<stop offset="0.49" stop-color="#D5EEF1"/>
<stop offset="0.87" stop-color="#B4E1EB"/>
<stop offset="1" stop-color="#A8DDE9"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -553,7 +553,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 31;
DEVELOPMENT_TEAM = 48V27SBR8J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -563,7 +563,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -745,7 +745,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 31;
DEVELOPMENT_TEAM = 48V27SBR8J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -755,7 +755,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -775,7 +775,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 31;
DEVELOPMENT_TEAM = 48V27SBR8J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -785,7 +785,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -862,7 +862,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 31;
DEVELOPMENT_TEAM = 48V27SBR8J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -872,7 +872,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -965,7 +965,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 31;
DEVELOPMENT_TEAM = 48V27SBR8J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -975,7 +975,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1063,7 +1063,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 31;
DEVELOPMENT_TEAM = 48V27SBR8J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -1073,7 +1073,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = com.example.syncrow.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -1,7 +1,7 @@
import UIKit
import Flutter
@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,

View File

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to allow you to select and upload photos.</string>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
@ -28,6 +26,8 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to allow you to select and upload photos.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
@ -36,10 +36,7 @@
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>

View File

@ -11,7 +11,7 @@ import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdo
import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/room_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
import 'package:syncrow_app/features/menu/view/menu_view.dart';
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
@ -55,7 +55,8 @@ 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,9 +77,12 @@ 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();
}
@ -88,7 +92,7 @@ class HomeCubit extends Cubit<HomeState> {
SpaceModel? selectedSpace;
RoomModel? selectedRoom;
SubSpaceModel? selectedRoom;
PageController devicesPageController = PageController();
@ -120,7 +124,9 @@ 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);
}
@ -128,21 +134,24 @@ class HomeCubit extends Cubit<HomeState> {
await OneSignal.User.pushSubscription.optIn();
//this function will be called once a user is subscribed
oneSignalSubscriptionObserver = OneSignal.User.pushSubscription.addObserver((state) async {
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 {
oneSignalPermissionObserver =
OneSignal.Notifications.addPermissionObserver((state) async {
await _sendSubscriptionId();
});
//check if the player id is sent, if not send it again
await _sendSubscriptionId();
oneSignalClickListenerObserver = OneSignal.Notifications.addClickListener((event) async {
oneSignalClickListenerObserver =
OneSignal.Notifications.addClickListener((event) async {
//Once the user clicks on the notification
});
} catch (err) {
@ -173,7 +182,7 @@ class HomeCubit extends Cubit<HomeState> {
if (index == 0) {
unselectRoom();
} else {
selectedRoom = selectedSpace!.rooms![index - 1];
selectedRoom = selectedSpace!.subspaces[index - 1];
emitSafe(RoomSelected(selectedRoom!));
}
}
@ -188,7 +197,7 @@ class HomeCubit extends Cubit<HomeState> {
if (index <= 0) {
unselectRoom();
} else {
selectedRoom = selectedSpace!.rooms![index - 1];
selectedRoom = selectedSpace!.subspaces[index - 1];
emitSafe(RoomSelected(selectedRoom!));
}
}
@ -211,9 +220,10 @@ class HomeCubit extends Cubit<HomeState> {
}
//////////////////////////////////////// API ////////////////////////////////////////
generateInvitation(String unitId) async {
generateInvitation(SpaceModel unit) async {
try {
final invitationCode = await SpacesAPI.generateInvitationCode(unitId);
final invitationCode =
await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
if (invitationCode.isNotEmpty) {
Share.share('The invitation code is $invitationCode');
CustomSnackBar.displaySnackBar(
@ -229,10 +239,12 @@ class HomeCubit extends Cubit<HomeState> {
Future<bool> joinAUnit(String code) async {
try {
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? '';
Map<String, String> body = {'userUuid': uuid, 'inviteCode': code};
var userUuid =
await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
'';
Map<String, String> body = {'inviteCode': code};
final success = await SpacesAPI.joinUnit(body);
final success = await SpacesAPI.joinUnit(userUuid, body);
if (success) {
await fetchUnitsByUserId();
CustomSnackBar.displaySnackBar('Done successfully');
@ -247,7 +259,7 @@ class HomeCubit extends Cubit<HomeState> {
fetchUnitsByUserId() async {
emitSafe(GetSpacesLoading());
try {
spaces = await SpacesAPI.getUnitsByUserId();
spaces = await SpacesAPI.getSpacesByUserId();
} catch (failure) {
emitSafe(GetSpacesError("No units found"));
return;
@ -265,13 +277,14 @@ class HomeCubit extends Cubit<HomeState> {
fetchRoomsByUnitId(SpaceModel space) async {
emitSafe(GetSpaceRoomsLoading());
try {
space.rooms = await SpacesAPI.getRoomsBySpaceId(space.id!);
space.subspaces =
await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
} catch (failure) {
emitSafe(GetSpaceRoomsError(failure.toString()));
return;
}
if (space.rooms != null && space.rooms!.isNotEmpty) {
emitSafe(GetSpaceRoomsSuccess(space.rooms!));
if (space.subspaces != null && space.subspaces!.isNotEmpty) {
emitSafe(GetSpaceRoomsSuccess(space.subspaces!));
} else {
emitSafe(GetSpaceRoomsError("No rooms found"));
}
@ -347,7 +360,8 @@ class HomeCubit extends Cubit<HomeState> {
size: 32,
),
style: ButtonStyle(
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
foregroundColor:
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {
Navigator.pushNamed(
@ -368,8 +382,12 @@ 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>()
.add(const ClearTabToRunSetting());
},
),
IconButton(
@ -378,7 +396,8 @@ class HomeCubit extends Cubit<HomeState> {
size: 28,
),
style: ButtonStyle(
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
foregroundColor:
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
@ -411,7 +430,8 @@ 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'),
@ -437,7 +457,8 @@ 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');
}
@ -445,7 +466,8 @@ 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

@ -33,7 +33,7 @@ class GetSpacesError extends HomeError {
class GetSpaceRoomsLoading extends HomeLoading {}
class GetSpaceRoomsSuccess extends HomeSuccess {
final List<RoomModel> rooms;
final List<SubSpaceModel> rooms;
GetSpaceRoomsSuccess(this.rooms);
}
@ -50,7 +50,7 @@ class SpaceSelected extends HomeState {
}
class RoomSelected extends HomeState {
final RoomModel room;
final SubSpaceModel room;
RoomSelected(this.room);
}

View File

@ -0,0 +1,27 @@
class Community {
final String uuid;
final String name;
final String description;
Community({
required this.uuid,
required this.name,
this.description = '',
});
factory Community.fromJson(Map<String, dynamic> json) {
return Community(
uuid: json['uuid'] ?? '',
name: json['name'] ?? 'Unnamed Community',
description: json['description'] ?? '',
);
}
Map<String, dynamic> toJson() {
return {
'uuid': uuid,
'name': name,
'description': description,
};
}
}

View File

@ -1,37 +1,53 @@
import 'package:syncrow_app/features/devices/model/room_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
class SpaceModel {
final String? id;
final String? name;
final SpaceType type;
late List<RoomModel>? rooms;
final String id;
final String name;
final Community community;
late List<SubSpaceModel> subspaces;
SpaceModel({
required this.type,
required this.id,
required this.name,
required this.rooms,
required this.community,
this.subspaces = const [], // Default to an empty list
});
/// Converts the instance into JSON format.
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'rooms': rooms,
'spaceName': name,
'community': community.toJson(),
'subspaces': subspaces.map((room) => room.toJson()).toList(),
};
}
/// Factory constructor to create an instance from JSON.
factory SpaceModel.fromJson(Map<String, dynamic> json) {
// Extract and log each part of space data
final id = json['uuid'] ?? '';
final name = json['spaceName'] ?? 'Unnamed Space';
final communityJson = json['community'] ?? {};
return SpaceModel(
id: json['uuid'],
name: json['name'],
type: spaceTypesMap[json['type']]!,
rooms: [],
id: id,
name: name,
community: Community.fromJson(
communityJson), // Ensure Community is created correctly
subspaces: (json['subspaces'] as List<dynamic>?)
?.map((item) => SubSpaceModel.fromJson(item))
.toList() ??
[],
);
}
/// Helper method to parse a list of SpaceModel from JSON.
static List<SpaceModel> fromJsonList(List<dynamic> jsonList) {
return jsonList.map((item) => SpaceModel.fromJson(item)).toList();
return jsonList.map((item) {
final spaceData = item['space']; // Extract the `space` object
return SpaceModel.fromJson(spaceData); // Pass to SpaceModel.fromJson
}).toList();
}
}

View File

@ -237,26 +237,34 @@ class AuthCubit extends Cubit<AuthState> {
}
}
sendOtp() async {
sendOtp({bool? isforget}) async {
try {
emit(AuthLoading());
await AuthenticationAPI.sendOtp(
body: {'email': email, 'type': 'VERIFICATION'});
await AuthenticationAPI.sendOtp(body: {
'email': email,
'type': isforget == true ? 'PASSWORD' : 'VERIFICATION'
});
emit(AuthSignUpSuccess());
} catch (_) {
emit(AuthLoginError(message: 'Something went wrong'));
emit(AuthErrorStatusWithoutMsg());
// emit(AuthLoginError(message: 'Something went wrong'));
}
}
Future<bool> reSendOtp() async {
Future<bool> reSendOtp({bool? forget}) async {
try {
emit(AuthLoading());
await AuthenticationAPI.sendOtp(
body: {'email': email, 'type': 'VERIFICATION'});
await AuthenticationAPI.sendOtp(body: {
'email': email,
'type': forget == true ? 'PASSWORD' : 'VERIFICATION'
});
emit(ResendOtpSuccess());
return true;
} catch (_) {
emit(AuthLoginError(message: 'Something went wrong'));
emit(AuthErrorStatusWithoutMsg());
// emit(AuthLoginError(message: 'Something went wrong'));
return false;
}
}
@ -264,8 +272,11 @@ class AuthCubit extends Cubit<AuthState> {
verifyOtp(bool isForgotPass) async {
emit(AuthLoginLoading());
try {
final response = await AuthenticationAPI.verifyPassCode(
body: {'email': email, 'type': 'VERIFICATION', 'otpCode': otpCode});
final response = await AuthenticationAPI.verifyPassCode(body: {
'email': email,
'type': isForgotPass == true ? 'PASSWORD' : 'VERIFICATION',
'otpCode': otpCode
});
if (response['statusCode'] == 200) {
if (!isForgotPass) {
emailController.text = email;
@ -273,11 +284,13 @@ class AuthCubit extends Cubit<AuthState> {
await login();
}
emit(AuthOtpSuccess());
} else {
emit(AuthLoginError(message: 'Something went wrong'));
}
// else {
// emit(AuthLoginError(message: 'Something went wrong'));
// }
} catch (failure) {
emit(AuthLoginError(message: 'Something went wrong'));
emit(AuthErrorStatusWithoutMsg());
//emit(AuthLoginError(message: 'Something went wrong'));
return;
}
}
@ -292,7 +305,9 @@ class AuthCubit extends Cubit<AuthState> {
(Route route) => false,
);
} catch (failure) {
emit(AuthLogoutError(message: 'Something went wrong'));
emit(AuthErrorStatusWithoutMsg());
// emit(AuthLogoutError(message: 'Something went wrong'));
return;
}
}
@ -333,17 +348,22 @@ class AuthCubit extends Cubit<AuthState> {
emit(AuthTokenError(message: "Something went wrong"));
}
} catch (_) {
emit(AuthTokenError(message: "Something went wrong"));
emit(AuthErrorStatusWithoutMsg());
// emit(AuthTokenError(message: "Something went wrong"));
}
}
sendToForgetPassword({required String password}) async {
try {
emit(AuthForgetPassLoading());
await AuthenticationAPI.forgetPassword(email: email, password: password);
await AuthenticationAPI.forgetPassword(
email: email, password: password, otpCode: otpCode);
emit(AuthForgetPassSuccess());
} catch (_) {
emit(AuthForgetPassError(message: 'Something went wrong'));
emit(AuthErrorStatusWithoutMsg());
// emit(AuthForgetPassError(message: 'Something went wrong'));
}
}
}

View File

@ -52,9 +52,6 @@ class AuthTokenError extends AuthError {
AuthTokenError({required super.message, super.code});
}
//ForgetPassword log states
class AuthForgetPassLoading extends AuthLoading {}
@ -64,3 +61,6 @@ class AuthForgetPassError extends AuthError {
AuthForgetPassError({required super.message, super.code});
}
class AuthErrorStatusWithoutMsg extends AuthState {
AuthErrorStatusWithoutMsg();
}

View File

@ -15,13 +15,15 @@ import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
import 'package:syncrow_app/utils/resource_manager/styles_manager.dart';
class checkEmailPage extends StatelessWidget {
const checkEmailPage({super.key});
bool? forget;
checkEmailPage({super.key, this.forget});
@override
Widget build(BuildContext context) {
final formKey = AuthCubit.get(context).checkEmailFormKey;
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarBrightness: Brightness.light, statusBarIconBrightness: Brightness.light));
statusBarBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light));
return BlocConsumer<AuthCubit, AuthState>(
listener: (context, state) {
if (state is AuthError) {
@ -34,8 +36,8 @@ class checkEmailPage extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const OtpView(
isForgetPage: true,
builder: (context) => OtpView(
isForgetPage: forget!,
),
));
}
@ -91,7 +93,9 @@ class checkEmailPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: MediaQuery.sizeOf(context).height / 5.5,
height:
MediaQuery.sizeOf(context).height /
5.5,
),
TitleMedium(
text: 'Forgot password?',
@ -113,32 +117,39 @@ class checkEmailPage extends StatelessWidget {
scrollPadding: EdgeInsets.zero,
autocorrect: false,
enableSuggestions: false,
autofillHints: const [AutofillHints.email],
validator: AuthCubit.get(context).emailAddressValidator,
autofillHints: const [
AutofillHints.email
],
validator: AuthCubit.get(context)
.emailAddressValidator,
onTapOutside: (event) {
FocusScope.of(context).unfocus();
},
onChanged: (value) {
AuthCubit.get(context).email = value;
},
decoration: defaultInputDecoration(context,
decoration: defaultInputDecoration(
context,
hint: "Example@email.com"),
),
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Expanded(
child: DefaultButton(
isDone: state is AuthLoginSuccess,
isLoading: state is AuthLoading,
customButtonStyle: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
backgroundColor:
MaterialStateProperty.all(
Colors.black.withOpacity(.25),
),
foregroundColor: MaterialStateProperty.all(
foregroundColor:
MaterialStateProperty.all(
Colors.white,
),
),
@ -146,11 +157,16 @@ class checkEmailPage extends StatelessWidget {
'Send Code',
),
onPressed: () {
AuthCubit.get(context).showValidationMessage = true;
if (formKey.currentState!.validate()) {
AuthCubit.get(context)
.showValidationMessage = true;
if (formKey.currentState!
.validate()) {
if ((state is! AuthLoading)) {
AuthCubit.get(context).sendOtp();
FocusScope.of(context).unfocus();
AuthCubit.get(context)
.sendOtp(
isforget: forget);
FocusScope.of(context)
.unfocus();
}
}
},
@ -160,14 +176,17 @@ class checkEmailPage extends StatelessWidget {
),
Padding(
padding: EdgeInsets.only(
top: MediaQuery.sizeOf(context).height / 5.5),
top: MediaQuery.sizeOf(context)
.height /
5.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
BodyLarge(
text: "Do you have an account? ",
style:
context.displaySmall.copyWith(color: Colors.white),
style: context.displaySmall
.copyWith(color: Colors.white),
),
TextButton(
onPressed: () {
@ -175,7 +194,8 @@ class checkEmailPage extends StatelessWidget {
},
child: BodyLarge(
text: "Sign in",
style: context.displaySmall.copyWith(
style:
context.displaySmall.copyWith(
color: Colors.black,
fontWeight: FontsManager.bold,
),

View File

@ -12,6 +12,7 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
import 'package:syncrow_app/utils/resource_manager/styles_manager.dart';
class CreateNewPasswordPage extends StatelessWidget {
const CreateNewPasswordPage({super.key,});

View File

@ -374,20 +374,25 @@ class _OtpViewState extends State<OtpView> {
return;
}
if ((state is! AuthLoading)) {
bool success = await AuthCubit.get(context)
.reSendOtp();
bool success =
await AuthCubit.get(context)
.reSendOtp(
forget:
widget.isForgetPage);
FocusScope.of(context).unfocus();
if(success){
showDialog(
context: context,
builder: (_) => SuccessDialog(
key: ValueKey('SuccessDialog'),
message: 'New OTP sent!',));
if (success) {
showDialog(
context: context,
builder: (_) =>const SuccessDialog(
key: ValueKey(
'SuccessDialog'),
message: 'New OTP sent!',
));
}
Future.delayed(Duration(seconds: 2),
() {
Navigator.of(context).pop();
});
// Future.delayed(Duration(seconds: 2),
// () {
// Navigator.of(context).pop();
// });
}
},
),

View File

@ -10,12 +10,17 @@ class ForgetPassword extends StatelessWidget {
@override
Widget build(BuildContext context) {
bool isforget = true;
return Row(
children: [
const Spacer(),
TextButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => const checkEmailPage(),));
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => checkEmailPage(forget: isforget),
));
},
child: BodyMedium(
text: "Forgot Password?",

View File

@ -64,7 +64,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList);
emit(GetAcStatusState(acStatusModel: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
_listenToChanges();
// _listenToChanges();
}
} catch (e) {
emit(AcsFailedState(errorMessage: e.toString()));

View File

@ -29,7 +29,7 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
}
deviceStatus = CeilingSensorModel.fromJson(statusModelList);
emit(UpdateState(ceilingSensorModel: deviceStatus));
_listenToChanges();
// _listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;

View File

@ -1,7 +1,11 @@
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/curtain_bloc/curtain_event.dart';
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart';
import 'package:syncrow_app/features/devices/model/curtain_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/group_curtain_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
@ -22,11 +26,14 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
on<OpenCurtain>(_onOpenCurtain);
on<CloseCurtain>(_onCloseCurtain);
on<PauseCurtain>(_onPauseCurtain);
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<InitialWizardEvent>(_fetchWizardStatus);
on<GroupAllOffEvent>(_groupAllOff);
on<GroupAllOnEvent>(_groupAllOn);
}
Future<void> _onOpenCurtain(
OpenCurtain event,
Emitter<CurtainState> emit) async {
OpenCurtain event, Emitter<CurtainState> emit) async {
isMoving = true;
while (openPercentage < 100.0) {
if (state is CurtainsClosing) {
@ -48,7 +55,7 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
_pauseCurtain(emit);
}
});
if (openPercentage >=100.0) {
if (openPercentage >= 100.0) {
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: curtainId,
@ -132,7 +139,7 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
),
curtainId,
);
await DevicesAPI.controlDevice(
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: curtainId,
code: 'percent_control',
@ -151,25 +158,18 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
));
}
void _fetchStatus(InitCurtain event, Emitter<CurtainState> emit) async {
try {
emit(CurtainLoadingState());
// Fetch the status from the API
var response = await DevicesAPI.getDeviceStatus(curtainId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
// Get the open percentage from the response
openPercentage = double.tryParse(statusModelList[1].value.toString())!;
// Calculate curtain width and blind height based on the open percentage
if (openPercentage != null) {
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
}
curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace;
blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace;
emit(CurtainsOpening(
curtainWidth: curtainWidth,
blindHeight: blindHeight,
@ -181,4 +181,138 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
}
}
List<GroupCurtainModel> groupList = [];
bool allSwitchesOn = true;
List<DeviceModel> devicesList = [];
CurtainModel deviceStatus = CurtainModel(control: 'stop', percent: 0);
void _fetchWizardStatus(
InitialWizardEvent event, Emitter<CurtainState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
groupList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', 'CUR');
for (int i = 0; i < devicesList.length; i++) {
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = CurtainModel.fromJson(statusModelList);
groupList.add(GroupCurtainModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.control,
percentControl: deviceStatus.percent));
}
if (groupList.isNotEmpty) {
groupList.firstWhere((element) {
if (element.percentControl > 1) {
allSwitchesOn = true;
}
return true;
});
}
emit(
UpdateGroupState(curtainList: groupList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState());
return;
}
}
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
Emitter<CurtainState> emit) async {
emit(LoadingNewSate(curtainModel: deviceStatus));
try {
bool allSwitchesValue = true;
// Update the firstSwitch value in the groupList based on the deviceId
groupList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.percentControl =
event.value; // Set the new value from the event
}
if (element.percentControl > 1) {
allSwitchesValue = true; // Check if any switch is not 'open'
}
});
final response = await DevicesAPI.deviceBatchController(
code: 'percent_control',
devicesUuid: [event.deviceId],
value: event.value, // Use the value from the event
);
emit(UpdateGroupState(
curtainList: groupList, allSwitches: allSwitchesValue));
if (response['success']) {
// Optionally add an initial event if needed.
}
} catch (_) {
// Handle the error if needed.
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<CurtainState> emit) async {
emit(LoadingNewSate(curtainModel: deviceStatus));
try {
for (int i = 0; i < groupList.length; i++) {
groupList[i].percentControl = 100;
}
emit(UpdateGroupState(curtainList: groupList, allSwitches: true));
List<String> allDeviceIds =
groupList.map((device) => device.deviceId).toList();
final response2 = await DevicesAPI.deviceBatchController(
code: 'percent_control',
devicesUuid: allDeviceIds,
value: 100,
);
if (response2['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
}
} catch (_) {
emit(FailedState());
await Future.delayed(const Duration(milliseconds: 500));
// Optionally add an initial event if needed.
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<CurtainState> emit) async {
emit(LoadingNewSate(curtainModel: deviceStatus));
try {
for (int i = 0; i < groupList.length; i++) {
groupList[i].percentControl = 0;
}
emit(UpdateGroupState(curtainList: groupList, allSwitches: false));
List<String> allDeviceIds =
groupList.map((device) => device.deviceId).toList();
final response2 = await DevicesAPI.deviceBatchController(
code: 'percent_control',
devicesUuid: allDeviceIds,
value: 0,
);
if (response2['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
}
} catch (_) {
emit(FailedState());
await Future.delayed(const Duration(milliseconds: 500));
}
}
}

View File

@ -31,4 +31,21 @@ class CloseCurtain extends CurtainEvent {
class InitCurtain extends CurtainEvent {}
class PauseCurtain extends CurtainEvent {}
class useCurtainEvent extends CurtainEvent {}
class useCurtainEvent extends CurtainEvent {}
class InitialWizardEvent extends CurtainEvent {}
class ChangeFirstWizardSwitchStatusEvent extends CurtainEvent {
final int value;
final String deviceId;
const ChangeFirstWizardSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class GroupAllOnEvent extends CurtainEvent {}
class GroupAllOffEvent extends CurtainEvent {}

View File

@ -1,5 +1,7 @@
// curtain_state.dart
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/curtain_model.dart';
import 'package:syncrow_app/features/devices/model/group_curtain_model.dart';
abstract class CurtainState extends Equatable {
const CurtainState();
@ -10,8 +12,9 @@ abstract class CurtainState extends Equatable {
class CurtainInitial extends CurtainState {}
class UpdateCurtain extends CurtainState {
class LoadingInitialState extends CurtainState {}
class UpdateCurtain extends CurtainState {
final double curtainWidth;
final double blindHeight;
final double openPercentage;
@ -73,4 +76,23 @@ class CurtainsPaused extends CurtainState {
@override
List<Object?> get props => [curtainWidth, blindHeight, openPercentage];
}
}
class UpdateGroupState extends CurtainState {
final List<GroupCurtainModel> curtainList;
final bool allSwitches;
const UpdateGroupState(
{required this.curtainList, required this.allSwitches});
@override
List<Object> get props => [curtainList, allSwitches];
}
class LoadingNewSate extends CurtainState {
final CurtainModel curtainModel;
const LoadingNewSate({required this.curtainModel});
@override
List<Object> get props => [curtainModel];
}

View File

@ -25,12 +25,14 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
static List<DevicesCategoryModel>? allCategories;
Future<void> _onFetchAllDevices(FetchAllDevices event, Emitter<DeviceManagerState> emit) async {
Future<void> _onFetchAllDevices(
FetchAllDevices event, Emitter<DeviceManagerState> emit) async {
emit(state.copyWith(loading: true));
try {
final allDevices = await HomeManagementAPI.fetchDevicesByUnitId();
emit(state.copyWith(devices: allDevices, loading: false));
} catch (e) {
print(e);
emit(state.copyWith(error: e.toString(), loading: false));
}
}
@ -39,21 +41,27 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
FetchDevicesByRoomId event, Emitter<DeviceManagerState> emit) async {
emit(state.copyWith(loading: true));
try {
final devices = await DevicesAPI.getDevicesByRoomId(event.roomId);
final devices = await DevicesAPI.getDevicesByRoomId(
communityUuid: event.unit.community.uuid,
spaceUuid: event.unit.id,
roomId: event.roomId,
);
emit(state.copyWith(devices: devices, loading: false));
} catch (e) {
emit(state.copyWith(error: e.toString(), loading: false));
}
}
void _onSelectCategory(SelectCategory event, Emitter<DeviceManagerState> emit) {
void _onSelectCategory(
SelectCategory event, Emitter<DeviceManagerState> emit) {
for (var i = 0; i < allCategories!.length; i++) {
allCategories![i].isSelected = i == event.index;
}
emit(state.copyWith(categoryChanged: true));
}
void _onUnselectAllCategories(UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
void _onUnselectAllCategories(
UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
for (var category in allCategories!) {
category.isSelected = false;
}
@ -97,7 +105,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
_updateDevicesStatus(category, emit);
}
void _onTurnOnOffDevice(TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
void _onTurnOnOffDevice(
TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
var device = event.device;
device.isOnline = !device.isOnline!;
DevicesCategoryModel category = allCategories!.firstWhere((category) {
@ -120,7 +129,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
emit(state.copyWith(categoryChanged: true)); // Set category changed state
}
void _updateDevicesStatus(DevicesCategoryModel category, Emitter<DeviceManagerState> emit) {
void _updateDevicesStatus(
DevicesCategoryModel category, Emitter<DeviceManagerState> emit) {
if (category.devices != null && category.devices!.isNotEmpty) {
bool? tempStatus = category.devices![0].isOnline;
for (var device in category.devices!) {
@ -140,7 +150,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
try {
final deviceFunctions = await DevicesAPI.deviceFunctions(event.deviceId);
emit(state.copyWith(functionsLoading: false, deviceFunctions: deviceFunctions));
emit(state.copyWith(
functionsLoading: false, deviceFunctions: deviceFunctions));
} catch (e) {
emit(state.copyWith(functionsLoading: false, error: e.toString()));
}

View File

@ -1,5 +1,6 @@
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/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
@ -15,8 +16,9 @@ class FetchAllDevices extends DeviceManagerEvent {}
class FetchDevicesByRoomId extends DeviceManagerEvent {
final String roomId;
final SpaceModel unit;
const FetchDevicesByRoomId(this.roomId);
const FetchDevicesByRoomId(this.roomId, this.unit);
@override
List<Object> get props => [roomId];

View File

@ -23,14 +23,22 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart';
part 'devices_state.dart';
class DevicesCubit extends Cubit<DevicesState> {
Future<void> _initializeDevices(SpaceModel selectedSpace) async {
// Fetch devices for each room in the selected space
for (var room in selectedSpace.subspaces ?? []) {
await fetchDevicesByRoomId(selectedSpace, room.id!);
}
// Fetch groups based on the selected space ID
await fetchGroups(selectedSpace.id ?? '');
}
DevicesCubit._() : super(DevicesInitial()) {
if (HomeCubit.getInstance().selectedSpace != null &&
HomeCubit.getInstance().spaces!.isNotEmpty) {
// fetchGroups(HomeCubit.getInstance().selectedSpace!.id!);
for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) {
fetchDevicesByRoomId(room.id!);
}
fetchGroups(HomeCubit.getInstance().selectedSpace?.id ?? '');
final selectedSpace = HomeCubit.getInstance().selectedSpace;
final spaces = HomeCubit.getInstance().spaces;
if (selectedSpace != null && spaces != null && spaces.isNotEmpty) {
_initializeDevices(selectedSpace);
}
}
@ -87,10 +95,10 @@ class DevicesCubit extends Cubit<DevicesState> {
return const DoorsListView();
case DeviceType.Curtain:
return const CurtainListView();
// case DeviceType.ThreeGang:
// return const ThreeGangSwitchesView();
// case DeviceType.Gateway:
// return const GateWayView();
// case DeviceType.ThreeGang:
// return const ThreeGangSwitchesView();
// case DeviceType.Gateway:
// return const GateWayView();
default:
return null;
}
@ -104,8 +112,8 @@ class DevicesCubit extends Cubit<DevicesState> {
List<DeviceModel> get allDevices {
List<DeviceModel> devices = [];
if (HomeCubit.getInstance().selectedSpace != null &&
HomeCubit.getInstance().selectedSpace!.rooms != null) {
for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) {
HomeCubit.getInstance().selectedSpace!.subspaces != null) {
for (var room in HomeCubit.getInstance().selectedSpace!.subspaces!) {
if (room.devices != null) {
devices.addAll(room.devices!);
}
@ -275,7 +283,7 @@ class DevicesCubit extends Cubit<DevicesState> {
deviceId,
HomeCubit.getInstance()
.selectedSpace!
.rooms!
.subspaces!
.indexOf(HomeCubit.getInstance().selectedRoom!),
code: control.code);
});
@ -303,20 +311,26 @@ class DevicesCubit extends Cubit<DevicesState> {
}
}
fetchDevicesByRoomId(String? roomId) async {
fetchDevicesByRoomId(SpaceModel? unit, String? roomId) async {
if (roomId == null) return;
emitSafe(GetDevicesLoading());
int roomIndex =
HomeCubit.getInstance().selectedSpace!.rooms!.indexWhere((element) => element.id == roomId);
int roomIndex = HomeCubit.getInstance()
.selectedSpace!
.subspaces!
.indexWhere((element) => element.id == roomId);
try {
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices =
await DevicesAPI.getDevicesByRoomId(roomId);
HomeCubit.getInstance().selectedSpace!.subspaces![roomIndex].devices =
await DevicesAPI.getDevicesByRoomId(
communityUuid: unit!.community.uuid,
spaceUuid: unit.id,
roomId: roomId);
} catch (e) {
emitSafe(GetDevicesError(e.toString()));
return;
}
final devices = HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices;
final devices =
HomeCubit.getInstance().selectedSpace!.subspaces![roomIndex].devices;
emitSafe(GetDevicesSuccess(devices));
//get status for each device
@ -333,7 +347,7 @@ class DevicesCubit extends Cubit<DevicesState> {
emitSafe(GetDeviceStatusLoading(code: code));
int deviceIndex = HomeCubit.getInstance()
.selectedSpace!
.rooms![roomIndex]
.subspaces![roomIndex]
.devices!
.indexWhere((element) => element.uuid == deviceUuid);
List<StatusModel> statuses = [];
@ -346,8 +360,11 @@ class DevicesCubit extends Cubit<DevicesState> {
emitSafe(GetDeviceStatusError(e.toString()));
return;
}
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices![deviceIndex].status =
statuses;
HomeCubit.getInstance()
.selectedSpace!
.subspaces![roomIndex]
.devices![deviceIndex]
.status = statuses;
emitSafe(GetDeviceStatusSuccess(code: code));
}
@ -396,8 +413,6 @@ class DevicesCubit extends Cubit<DevicesState> {
// emitSafe(LightBrightnessChanged(value));
// }
// }
}
enum LightMode {

View File

@ -1,5 +1,4 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -26,11 +25,9 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
bool lowBattery = false;
bool closingReminder = false;
bool doorAlarm = false;
DoorSensorModel deviceStatus =
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
DoorSensorModel deviceStatus = DoorSensorModel(doorContactState: false, batteryPercentage: 0);
void _fetchStatus(
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
void _fetchStatus(DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
emit(DoorSensorLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(DSId);
@ -43,7 +40,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
);
emit(UpdateState(doorSensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
_listenToChanges();
// _listenToChanges();
} catch (e) {
emit(DoorSensorFailedState(errorMessage: e.toString()));
return;
@ -51,8 +48,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
// Toggle functions for each switch
void _toggleLowBattery(
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
void _toggleLowBattery(ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
lowBattery = event.isLowBatteryEnabled;
@ -93,14 +89,12 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
}
void _toggleDoorAlarm(
ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
doorAlarm = event.isDoorAlarmEnabled;
emit(UpdateState(doorSensor: deviceStatus));
// API call to update the state, if necessary
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: DSId,
@ -114,53 +108,41 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
}
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []);
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
// Get the current date and time
Future<void> fetchLogsForLastMonth(ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
DateTime now = DateTime.now();
// Calculate the date one month ago
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
// Convert the date to milliseconds since epoch (Unix timestamp in milliseconds)
int startTime = lastMonth.millisecondsSinceEpoch;
int endTime = now.millisecondsSinceEpoch;
try {
emit(DoorSensorLoadingState());
var response = await DevicesAPI.getReportLogs(
startTime:
startTime.toString(), // Convert to String if the API expects it
endTime: endTime.toString(), // Convert to String if the API expects it
startTime: startTime.toString(),
endTime: endTime.toString(),
deviceUuid: DSId,
code: 'doorcontact_state',
);
print('response======${response}');
recordGroups = response;
// Process response here
emit(UpdateState(doorSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
// Handle error
print('Error fetching logs: ${errorMessage}');
}
}
_listenToChanges() {
try {
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$DSId');
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$DSId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {

View File

@ -0,0 +1,592 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart';
import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_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/garage_door_model.dart';
import 'package:syncrow_app/features/devices/model/group_garage_model.dart';
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
final String GDId;
GarageDoorBloc({
required this.GDId,
}) : super(const GarageDoorSensorState()) {
on<GarageDoorInitial>(_fetchStatus);
on<ReportLogsInitial>(fetchLogsForLastMonth);
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
on<ToggleDoorAlarmEvent>(_toggleDoorAlarm);
on<ToggleDaySelectionEvent>(toggleDaySelection);
on<ScheduleSaveapp>(saveSchedule);
on<GetScheduleEvent>(getSchedule);
on<ToggleScheduleEvent>(toggleChange);
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
on<OnClose>(_onClose);
on<SelectSecondsEvent>(selectSeconds);
on<ToggleDoorEvent>(openCloseGarageDoor);
on<GetCounterEvent>(_getCounterValue);
on<SetCounterValue>(_setCounterValue);
on<SetTimeOutValue>(_setTimeOutAlarm);
on<TickTimer>(_onTickTimer);
on<InitialWizardEvent>(_fetchWizardStatus);
on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff);
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<ToggleAlarmEvent>(_toggleAlarmEvent);
on<DeleteScheduleEvent>(deleteSchedule);
//_toggleAlarmEvent
}
void _onClose(OnClose event, Emitter<GarageDoorSensorState> emit) {
_timer?.cancel();
}
Timer? _timer;
bool lowBattery = false;
bool closingReminder = false;
bool doorAlarm = false;
GarageDoorModel deviceStatus = GarageDoorModel(
tr_timecon: 0,
countdown1: 0,
countdownAlarm: 0,
doorContactState: false,
doorControl1: '',
doorState1: '',
switch1: false,
voiceControl1: false,
batteryPercentage: 0,
);
void _fetchStatus(GarageDoorInitial event, Emitter<GarageDoorSensorState> emit) async {
emit(GarageDoorLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(GDId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = GarageDoorModel.fromJson(
statusModelList,
);
secondSelected = deviceStatus.tr_timecon;
toggleDoor = deviceStatus.switch1;
emit(UpdateState(garageSensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
return;
}
}
void _toggleAlarmEvent(
ToggleAlarmEvent event,
Emitter<GarageDoorSensorState> emit,
) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
deviceStatus.doorState1 = event.isEnabled;
emit(UpdateState(garageSensor: deviceStatus));
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: GDId,
code: 'door_state_1',
value: event.isEnabled,
),
GDId,
);
emit(UpdateState(garageSensor: deviceStatus));
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
}
}
void _toggleClosingReminder(
ToggleClosingReminderEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
closingReminder = event.isClosingReminderEnabled;
emit(UpdateState(garageSensor: deviceStatus));
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: GDId,
code: 'closing_reminder',
value: closingReminder,
),
GDId,
);
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
}
}
void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
doorAlarm = event.isDoorAlarmEnabled;
emit(UpdateState(garageSensor: deviceStatus));
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: GDId,
code: 'door_alarm',
value: doorAlarm,
),
GDId,
);
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
}
}
DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []);
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<GarageDoorSensorState> emit) async {
DateTime now = DateTime.now();
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
int startTime = lastMonth.millisecondsSinceEpoch;
int endTime = now.millisecondsSinceEpoch;
try {
emit(GarageDoorLoadingState());
var response = await DevicesAPI.getReportLogs(
startTime: startTime.toString(),
endTime: endTime.toString(),
deviceUuid: GDId,
code: 'switch_1',
);
recordGroups = response;
emit(UpdateState(garageSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(GarageDoorFailedState(errorMessage: errorMessage));
}
}
_listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$GDId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: true));
});
deviceStatus = GarageDoorModel.fromJson(statusList);
if (!isClosed) {
// add(
// DoorSensorSwitch(switchD: deviceStatus.doorContactState),
// );
}
});
} catch (_) {}
}
List<Map<String, String>> days = [
{"day": "Sun", "key": "Sun"},
{"day": "Mon", "key": "Mon"},
{"day": "Tue", "key": "Tue"},
{"day": "Wed", "key": "Wed"},
{"day": "Thu", "key": "Thu"},
{"day": "Fri", "key": "Fri"},
{"day": "Sat", "key": "Sat"},
];
Future<void> toggleDaySelection(
ToggleDaySelectionEvent event,
Emitter<GarageDoorSensorState> emit,
) async {
emit(GarageDoorLoadingState());
if (selectedDays.contains(event.key)) {
selectedDays.remove(event.key);
} else {
selectedDays.add(event.key);
}
emit(ChangeTimeState());
}
Future<void> saveSchedule(
ScheduleSaveapp event,
Emitter<GarageDoorSensorState> emit,
) async {
try {
if (selectedDays.isNotEmpty) {
emit(GarageDoorLoadingState());
await DevicesAPI.postSchedule(
category: 'switch_1',
deviceId: GDId,
time: getTimeStampWithoutSeconds(selectedTime).toString(),
code: 'switch_1',
value: toggleSchedule,
days: selectedDays);
CustomSnackBar.displaySnackBar('Save Successfully');
add(GetScheduleEvent());
add(const ToggleCreateScheduleEvent(index: 1));
} else {
CustomSnackBar.displaySnackBar('Please select days');
}
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
}
}
Future<void> getSchedule(
GetScheduleEvent event,
Emitter<GarageDoorSensorState> emit,
) async {
try {
emit(GarageDoorLoadingState());
final response = await DevicesAPI.getSchedule(
category: 'switch_1',
deviceId: GDId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(UpdateState(garageSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(GarageDoorFailedState(errorMessage: errorMessage.toString()));
}
}
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<GarageDoorSensorState> emit) async {
try {
emit(GarageDoorLoadingState());
final response = await DevicesAPI.changeSchedule(
scheduleId: event.id, deviceUuid: GDId, enable: event.toggle);
if (response == true) {
add(GetScheduleEvent());
toggleSchedule = event.toggle;
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(GarageDoorFailedState(errorMessage: errorMessage.toString()));
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<GarageDoorSensorState> emit) async {
try {
emit(GarageDoorLoadingState());
final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id,
deviceUuid: GDId,
);
if (response == true) {
add(GetScheduleEvent());
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(GarageDoorFailedState(errorMessage: errorMessage.toString()));
}
}
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<GarageDoorSensorState> emit) {
emit(GarageDoorLoadingState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<GarageDoorSensorState> emit) {
emit(GarageDoorLoadingState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
int selectedTabIndex = 0;
bool toggleSchedule = true;
List<String> selectedDays = [];
bool createSchedule = false;
List<ScheduleModel> listSchedule = [];
DateTime? selectedTime = DateTime.now();
int secondSelected = 0;
bool toggleDoor = false;
Future<void> selectSeconds(SelectSecondsEvent event, Emitter<GarageDoorSensorState> emit) async {
try {
emit(GarageDoorLoadingState());
secondSelected = event.seconds;
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: GDId, code: 'tr_timecon', value: secondSelected), GDId);
emit(UpdateState(garageSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(GarageDoorFailedState(errorMessage: errorMessage.toString()));
}
}
openCloseGarageDoor(ToggleDoorEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(GarageDoorLoadingState());
try {
toggleDoor = !event.toggle;
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: GDId, code: 'switch_1', value: toggleDoor), GDId);
add(const GarageDoorInitial());
emit(UpdateState(garageSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(GarageDoorFailedState(errorMessage: errorMessage.toString()));
}
}
void _setCounterValue(SetCounterValue event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: GDId, code: 'countdown_1', value: seconds), GDId);
if (response['success'] ?? false) {
deviceStatus.countdown1 = seconds;
} else {
emit(const GarageDoorFailedState(errorMessage: 'Something went wrong'));
return;
}
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
return;
}
if (seconds > 0) {
_onStartTimer(seconds);
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
void _getCounterValue(GetCounterEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(GDId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = GarageDoorModel.fromJson(statusModelList);
if (event.deviceCode == 'countdown_1') {
deviceStatus.countdown1 > 0
? _onStartTimer(deviceStatus.countdown1)
: emit(UpdateTimerState(seconds: deviceStatus.countdown1));
}
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
return;
}
}
void _onStartTimer(int seconds) {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
add(TickTimer(remainingTime: seconds - timer.tick));
});
}
void _onTickTimer(TickTimer event, Emitter<GarageDoorSensorState> emit) {
if (event.remainingTime > 0) {
emit(TimerRunInProgress(event.remainingTime));
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
bool oneGangGroup = false;
List<DeviceModel> devicesList = [];
List<GroupGarageModel> groupList = [];
bool allSwitchesOn = true;
void _fetchWizardStatus(InitialWizardEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
groupList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', 'GD');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = GarageDoorModel.fromJson(statusModelList);
groupList.add(GroupGarageModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.switch1,
));
}
if (groupList.isNotEmpty) {
groupList.firstWhere((element) {
if (!element.firstSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(garageList: groupList, allSwitches: allSwitchesOn));
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
return;
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
for (int i = 0; i < groupList.length; i++) {
groupList[i].firstSwitch = true;
}
// Emit the state with updated values
emit(UpdateGroupState(garageList: groupList, allSwitches: true));
// Get a list of all device IDs
List<String> allDeviceIds = groupList.map((device) => device.deviceId).toList();
// First call for switch_1
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1', // Controls first switch for all devices
devicesUuid: allDeviceIds,
value: true, // true (on) or false (off) depending on the event value
);
// Check if either response is unsuccessful, then reset to initial state
if (response['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
// In case of an error, delay and reset the screen to initial state
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
for (int i = 0; i < groupList.length; i++) {
groupList[i].firstSwitch = false;
}
// Emit the state with updated values
emit(UpdateGroupState(garageList: groupList, allSwitches: false));
// Get a list of all device IDs
List<String> allDeviceIds = groupList.map((device) => device.deviceId).toList();
// First call for switch_1
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1', // Controls first switch for all devices
devicesUuid: allDeviceIds,
value: false, // true (on) or false (off) depending on the event value
);
// Check if either response is unsuccessful, then reset to initial state
if (response['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
// In case of an error, delay and reset the screen to initial state
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
bool allSwitchesValue = true;
groupList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(garageList: groupList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: [event.deviceId],
value: !event.value,
);
if (response['failedResults'].toString() != '[]') {
add(InitialEvent(groupScreen: oneGangGroup));
}
} catch (_) {
add(InitialEvent(groupScreen: oneGangGroup));
}
}
void _setTimeOutAlarm(SetTimeOutValue event, Emitter<GarageDoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: GDId, code: 'countdown_alarm', value: seconds), GDId);
if (response['success'] ?? false) {
deviceStatus.countdownAlarm = seconds;
CustomSnackBar.displaySnackBar('Save Successfully');
add(GetScheduleEvent());
} else {
emit(const GarageDoorFailedState(errorMessage: 'Something went wrong'));
return;
}
} catch (e) {
emit(GarageDoorFailedState(errorMessage: e.toString()));
return;
}
}
}

View File

@ -0,0 +1,183 @@
import 'package:equatable/equatable.dart';
abstract class GarageDoorEvent extends Equatable {
const GarageDoorEvent();
@override
List<Object> get props => [];
}
class GarageDoorLoading extends GarageDoorEvent {}
class GarageDoorSwitch extends GarageDoorEvent {
final bool switchD;
final String deviceId;
final String productId;
const GarageDoorSwitch(
{required this.switchD, this.deviceId = '', this.productId = ''});
@override
List<Object> get props => [switchD, deviceId, productId];
}
class GarageDoorUpdated extends GarageDoorEvent {}
class GarageDoorInitial extends GarageDoorEvent {
const GarageDoorInitial();
}
class ReportLogsInitial extends GarageDoorEvent {
const ReportLogsInitial();
}
class GarageDoorChangeStatus extends GarageDoorEvent {}
class GetCounterEvent extends GarageDoorEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class ToggleAlarmEvent extends GarageDoorEvent {
final String isEnabled;
const ToggleAlarmEvent(this.isEnabled);
@override
List<Object> get props => [isEnabled];
}
class ToggleClosingReminderEvent extends GarageDoorEvent {
final bool isClosingReminderEnabled;
const ToggleClosingReminderEvent(this.isClosingReminderEnabled);
@override
List<Object> get props => [isClosingReminderEnabled];
}
class ToggleDoorAlarmEvent extends GarageDoorEvent {
final bool isDoorAlarmEnabled;
const ToggleDoorAlarmEvent(this.isDoorAlarmEnabled);
@override
List<Object> get props => [isDoorAlarmEnabled];
}
class SetCounterValue extends GarageDoorEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class SetTimeOutValue extends GarageDoorEvent {
final Duration duration;
final String deviceCode;
const SetTimeOutValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends GarageDoorEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends GarageDoorEvent {
final int remainingTime;
const TickTimer({required this.remainingTime});
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends GarageDoorEvent {}
class OnClose extends GarageDoorEvent {}
//------------------- Schedule ----------=---------
class GetScheduleEvent extends GarageDoorEvent {}
class ScheduleSaveapp extends GarageDoorEvent {}
class ToggleScheduleEvent extends GarageDoorEvent {
final String id;
final bool toggle;
const ToggleScheduleEvent({required this.toggle, required this.id});
@override
List<Object> get props => [toggle, id];
}
class ToggleDaySelectionEvent extends GarageDoorEvent {
final String key;
const ToggleDaySelectionEvent({required this.key});
@override
List<Object> get props => [key];
}
class DeleteScheduleEvent extends GarageDoorEvent {
final String id;
const DeleteScheduleEvent({required this.id});
@override
List<Object> get props => [id];
}
class ToggleSelectedEvent extends GarageDoorEvent {
final int index;
const ToggleSelectedEvent({required this.index});
@override
List<Object> get props => [index];
}
class ToggleCreateScheduleEvent extends GarageDoorEvent {
final int index;
const ToggleCreateScheduleEvent({required this.index});
@override
List<Object> get props => [index];
}
class ChangeFirstWizardSwitchStatusEvent extends GarageDoorEvent {
final bool value;
final String deviceId;
const ChangeFirstWizardSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class SelectSecondsEvent extends GarageDoorEvent {
final int seconds;
const SelectSecondsEvent({required this.seconds});
@override
List<Object> get props => [seconds];
}
class ToggleDoorEvent extends GarageDoorEvent {
final bool toggle;
const ToggleDoorEvent({required this.toggle});
@override
List<Object> get props => [toggle];
}
class InitialWizardEvent extends GarageDoorEvent {}
class GroupAllOnEvent extends GarageDoorEvent {}
class GroupAllOffEvent extends GarageDoorEvent {}
class InitialEvent extends GarageDoorEvent {
final bool groupScreen;
const InitialEvent({required this.groupScreen});
@override
List<Object> get props => [groupScreen];
}

View File

@ -0,0 +1,94 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/garage_door_model.dart';
import 'package:syncrow_app/features/devices/model/group_garage_model.dart';
class GarageDoorSensorState extends Equatable {
const GarageDoorSensorState();
@override
List<Object> get props => [];
}
class GarageDoorInitialState extends GarageDoorSensorState {}
class GarageDoorLoadingState extends GarageDoorSensorState {}
class GarageDoorFailedState extends GarageDoorSensorState {
final String errorMessage;
const GarageDoorFailedState({required this.errorMessage});
@override
List<Object> get props => [errorMessage];
}
class UpdateState extends GarageDoorSensorState {
final GarageDoorModel garageSensor;
const UpdateState({required this.garageSensor});
@override
List<Object> get props => [garageSensor];
}
class LoadingNewSate extends GarageDoorSensorState {
final GarageDoorModel doorSensor;
const LoadingNewSate({required this.doorSensor});
@override
List<Object> get props => [doorSensor];
}
class ChangeSlidingSegmentState extends GarageDoorSensorState {
final int value;
const ChangeSlidingSegmentState({required this.value});
@override
List<Object> get props => [value];
}
class UpdateTimerState extends GarageDoorSensorState {
final int seconds;
const UpdateTimerState({required this.seconds});
@override
List<Object> get props => [seconds];
}
class TimerRunInProgress extends GarageDoorSensorState {
final int remainingTime;
const TimerRunInProgress(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class TimerRunComplete extends GarageDoorSensorState {}
class SaveSchedule extends GarageDoorSensorState {}
class IsToggleState extends GarageDoorSensorState {
final bool? onOff;
const IsToggleState({this.onOff});
}
class ChangeTimeState extends GarageDoorSensorState {}
class LoadingInitialState extends GarageDoorSensorState {}
class UpdateCreateScheduleState extends GarageDoorSensorState {
final bool createSchedule;
UpdateCreateScheduleState(this.createSchedule);
}
class UpdateGroupState extends GarageDoorSensorState {
final List<GroupGarageModel> garageList;
final bool allSwitches;
const UpdateGroupState(
{required this.garageList, required this.allSwitches});
@override
List<Object> get props => [garageList, allSwitches];
}

View File

@ -2,9 +2,11 @@ import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/group_one_gang_model.dart';
import 'package:syncrow_app/features/devices/model/one_gang_model.dart';
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
@ -41,6 +43,10 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
on<DeleteScheduleEvent>(deleteSchedule);
on<ToggleSelectedEvent>(toggleSelectedIndex);
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
on<InitialWizardEvent>(_fetchOneGangWizardStatus);
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff);
}
void _fetchOneGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
@ -53,7 +59,7 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
deviceStatus = OneGangModel.fromJson(statusModelList);
emit(UpdateState(oneGangModel: deviceStatus));
_listenToChanges();
// _listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
@ -215,7 +221,7 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
add(GetScheduleEvent());
emit(SaveSchedule());
add(const ToggleCreateScheduleEvent(index:1 ));
add(const ToggleCreateScheduleEvent(index: 1));
} else {
CustomSnackBar.displaySnackBar('Please select days');
}
@ -290,23 +296,13 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
}
}
// void toggleCreateSchedule() {
// emit(LoadingInitialState());
// createSchedule = !createSchedule;
// selectedDays.clear();
// selectedTime = DateTime.now();
// emit(UpdateCreateScheduleState(createSchedule));
// emit(ChangeSlidingSegmentState(value: 1));
// }
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<OneGangState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
bool toggleSchedule = true;
List<String> selectedDays = [];
@ -324,14 +320,150 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
selectedDays.add(event.key);
}
emit(ChangeTimeState());
add(ChangeSlidingSegment(value: 1));
add(const ChangeSlidingSegment(value: 1));
}
int selectedTabIndex = 0;
void toggleSelectedIndex( ToggleSelectedEvent event, Emitter<OneGangState> emit) {
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<OneGangState> emit) {
emit(LoadingInitialState());
selectedTabIndex =event.index;
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
List<GroupOneGangModel> groupOneGangList = [];
bool allSwitchesOn = true;
void _fetchOneGangWizardStatus(InitialWizardEvent event, Emitter<OneGangState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
groupOneGangList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', '1G');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = OneGangModel.fromJson(statusModelList);
groupOneGangList.add(GroupOneGangModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
));
}
if (groupOneGangList.isNotEmpty) {
groupOneGangList.firstWhere((element) {
if (!element.firstSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<OneGangState> emit) async {
emit(LoadingNewSate(oneGangModel: deviceStatus));
try {
bool allSwitchesValue = true;
groupOneGangList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: [event.deviceId],
value: !event.value,
);
if (response['failedResults'].toString() != '[]') {
add(InitialEvent(groupScreen: oneGangGroup));
}
} catch (_) {
add(InitialEvent(groupScreen: oneGangGroup));
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<OneGangState> emit) async {
emit(LoadingNewSate(oneGangModel: deviceStatus));
try {
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
for (int i = 0; i < groupOneGangList.length; i++) {
groupOneGangList[i].firstSwitch = true;
}
// Emit the state with updated values
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: true));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList();
// First call for switch_1
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1', // Controls first switch for all devices
devicesUuid: allDeviceIds,
value: true, // true (on) or false (off) depending on the event value
);
// Check if either response is unsuccessful, then reset to initial state
if (response['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
// In case of an error, delay and reset the screen to initial state
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<OneGangState> emit) async {
emit(LoadingNewSate(oneGangModel: deviceStatus));
try {
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
for (int i = 0; i < groupOneGangList.length; i++) {
groupOneGangList[i].firstSwitch = false;
}
// Emit the state with updated values
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: false));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList();
// First call for switch_1
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1', // Controls first switch for all devices
devicesUuid: allDeviceIds,
value: false, // true (on) or false (off) depending on the event value
);
// Check if either response is unsuccessful, then reset to initial state
if (response['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
// In case of an error, delay and reset the screen to initial state
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
}

View File

@ -29,12 +29,12 @@ class ChangeFirstSwitchStatusEvent extends OneGangEvent {
class ChangeSecondSwitchStatusEvent extends OneGangEvent {
final bool value;
final String deviceId;
const ChangeSecondSwitchStatusEvent({required this.value, this.deviceId = ''});
const ChangeSecondSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class AllOffEvent extends OneGangEvent {}
class AllOnEvent extends OneGangEvent {}
@ -87,27 +87,29 @@ class StopTimer extends OneGangEvent {}
class OnClose extends OneGangEvent {}
class InitialWizardEvent extends OneGangEvent {}
//------------------- Schedule ----------=---------
class GetScheduleEvent extends OneGangEvent {}
class ScheduleSave extends OneGangEvent {}
class ToggleScheduleEvent extends OneGangEvent {
final String id;
final bool toggle;
const ToggleScheduleEvent({required this.toggle,required this.id});
const ToggleScheduleEvent({required this.toggle, required this.id});
@override
List<Object> get props => [toggle,id];
List<Object> get props => [toggle, id];
}
class ToggleDaySelectionEvent extends OneGangEvent {
class ToggleDaySelectionEvent extends OneGangEvent {
final String key;
const ToggleDaySelectionEvent({required this.key});
@override
List<Object> get props => [key];
}
class DeleteScheduleEvent extends OneGangEvent {
final String id;
const DeleteScheduleEvent({required this.id});
@ -115,7 +117,6 @@ class DeleteScheduleEvent extends OneGangEvent {
List<Object> get props => [id];
}
class ToggleSelectedEvent extends OneGangEvent {
final int index;
const ToggleSelectedEvent({required this.index});
@ -123,10 +124,18 @@ class ToggleSelectedEvent extends OneGangEvent {
List<Object> get props => [index];
}
class ToggleCreateScheduleEvent extends OneGangEvent {
final int index;
const ToggleCreateScheduleEvent({required this.index});
@override
List<Object> get props => [index];
}
class ChangeFirstWizardSwitchStatusEvent extends OneGangEvent {
final bool value;
final String deviceId;
const ChangeFirstWizardSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}

View File

@ -0,0 +1,512 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/foundation.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/one_touch_bloc/one_touch_state.dart';
import 'package:syncrow_app/features/devices/bloc/one_touch_bloc/one_touch_event.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/group_one_touch_model.dart';
import 'package:syncrow_app/features/devices/model/one_touch_model.dart';
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class OneTouchBloc extends Bloc<OneTouchEvent, OneTouchState> {
final String oneTouchId;
final String switchCode;
OneTouchModel deviceStatus = OneTouchModel(
firstSwitch: false,
firstCountDown: 0,
light_mode: lightStatus.off,
relay: status.off,
relay_status_1: status.off);
Timer? _timer;
bool oneTouchGroup = false;
List<DeviceModel> devicesList = [];
OneTouchBloc({required this.oneTouchId, required this.switchCode}) : super(InitialState()) {
on<InitialEvent>(_fetchOneTouchStatus);
on<OneTouchUpdated>(_oneTouchUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
on<ChangeSlidingSegment>(_changeSliding);
on<SetCounterValue>(_setCounterValue);
on<GetCounterEvent>(_getCounterValue);
on<TickTimer>(_onTickTimer);
on<OnClose>(_onClose);
on<ToggleDaySelectionEvent>(toggleDaySelection);
on<ScheduleSave>(saveSchedule);
on<GetScheduleEvent>(getSchedule);
on<ToggleScheduleEvent>(toggleChange);
on<DeleteScheduleEvent>(deleteSchedule);
on<ToggleSelectedEvent>(toggleSelectedIndex);
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
on<InitialWizardEvent>(_fetchOneTouchWizardStatus);
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff);
on<ChangeStatusEvent>(_changeStatus);
}
void _fetchOneTouchStatus(InitialEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = OneTouchModel.fromJson(statusModelList);
emit(UpdateState(oneTouchModel: deviceStatus));
// _listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneTouchId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = OneTouchModel.fromJson(statusList);
if (!isClosed) {
add(OneTouchUpdated());
}
});
} catch (_) {}
}
_oneTouchUpdated(OneTouchUpdated event, Emitter<OneTouchState> emit) {
emit(UpdateState(oneTouchModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
try {
deviceStatus.firstSwitch = !event.value;
emit(UpdateState(oneTouchModel: deviceStatus));
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 500), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: oneTouchGroup ? event.deviceId : oneTouchId,
code: 'switch_1',
value: !event.value),
oneTouchGroup ? event.deviceId : oneTouchId);
if (!response['success']) {
add(InitialEvent(groupScreen: oneTouchGroup));
}
});
} catch (_) {
add(InitialEvent(groupScreen: oneTouchGroup));
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<OneTouchState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: oneTouchId, code: event.deviceCode, value: seconds),
oneTouchId);
if (response['success'] ?? false) {
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown = seconds;
}
} else {
emit(const FailedState(error: 'Something went wrong'));
return;
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
if (seconds > 0) {
_onStartTimer(seconds);
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
void _getCounterValue(GetCounterEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(oneTouchId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = OneTouchModel.fromJson(statusModelList);
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown > 0
? _onStartTimer(deviceStatus.firstCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _onClose(OnClose event, Emitter<OneTouchState> emit) {
_timer?.cancel();
}
void _onStartTimer(int seconds) {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
add(TickTimer(seconds - timer.tick));
});
}
void _onTickTimer(TickTimer event, Emitter<OneTouchState> emit) {
if (event.remainingTime > 0) {
emit(TimerRunInProgress(event.remainingTime));
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
List<Map<String, String>> days = [
{"day": "Sun", "key": "Sun"},
{"day": "Mon", "key": "Mon"},
{"day": "Tue", "key": "Tue"},
{"day": "Wed", "key": "Wed"},
{"day": "Thu", "key": "Thu"},
{"day": "Fri", "key": "Fri"},
{"day": "Sat", "key": "Sat"},
];
Future<void> saveSchedule(
ScheduleSave event,
Emitter<OneTouchState> emit,
) async {
try {
if (selectedDays.isNotEmpty) {
emit(LoadingInitialState());
await DevicesAPI.postSchedule(
category: switchCode,
deviceId: oneTouchId,
time: getTimeStampWithoutSeconds(selectedTime).toString(),
code: switchCode,
value: toggleSchedule,
days: selectedDays);
CustomSnackBar.displaySnackBar('Save Successfully');
add(GetScheduleEvent());
emit(SaveSchedule());
add(const ToggleCreateScheduleEvent(index: 1));
} else {
CustomSnackBar.displaySnackBar('Please select days');
}
} catch (e) {
emit(FailedState(error: e.toString()));
}
}
Future<void> getSchedule(
GetScheduleEvent event,
Emitter<OneTouchState> emit,
) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.getSchedule(
category: switchCode,
deviceId: oneTouchId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<OneTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
scheduleId: event.id, deviceUuid: oneTouchId, enable: event.toggle);
if (response == true) {
add(GetScheduleEvent());
toggleSchedule = event.toggle;
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
add(const ChangeSlidingSegment(value: 1));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<OneTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id,
deviceUuid: oneTouchId,
);
if (response == true) {
add(GetScheduleEvent());
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
add(const ChangeSlidingSegment(value: 1));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<OneTouchState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
bool toggleSchedule = true;
List<String> selectedDays = [];
bool createSchedule = false;
List<ScheduleModel> listSchedule = [];
DateTime? selectedTime = DateTime.now();
Future<void> toggleDaySelection(
ToggleDaySelectionEvent event,
Emitter<OneTouchState> emit,
) async {
emit(LoadingInitialState());
if (selectedDays.contains(event.key)) {
selectedDays.remove(event.key);
} else {
selectedDays.add(event.key);
}
emit(ChangeTimeState());
add(ChangeSlidingSegment(value: 1));
}
int selectedTabIndex = 0;
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<OneTouchState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
List<GroupOneTouchModel> groupOneTouchList = [];
bool allSwitchesOn = true;
void _fetchOneTouchWizardStatus(InitialWizardEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
groupOneTouchList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', '1GT');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = OneTouchModel.fromJson(statusModelList);
groupOneTouchList.add(GroupOneTouchModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
));
}
if (groupOneTouchList.isNotEmpty) {
groupOneTouchList.firstWhere((element) {
if (!element.firstSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
try {
bool allSwitchesValue = true;
groupOneTouchList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch) {
allSwitchesValue = false;
}
});
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: [event.deviceId],
value: !event.value,
);
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue));
if (response['success']) {
add(InitialEvent(groupScreen: oneTouchGroup));
}
} catch (_) {
add(InitialEvent(groupScreen: oneTouchGroup));
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
try {
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
for (int i = 0; i < groupOneTouchList.length; i++) {
groupOneTouchList[i].firstSwitch = true;
}
// Emit the state with updated values
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: true));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneTouchList.map((device) => device.deviceId).toList();
// First call for switch_1
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1', // Controls first switch for all devices
devicesUuid: allDeviceIds,
value: true, // true (on) or false (off) depending on the event value
);
if (response1['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
emit(FailedState(error: _.toString()));
// In case of an error, delay and reset the screen to initial state
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<OneTouchState> emit) async {
emit(LoadingNewSate(oneTouchModel: deviceStatus));
try {
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
for (int i = 0; i < groupOneTouchList.length; i++) {
groupOneTouchList[i].firstSwitch = false;
}
// Emit the state with updated values
emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: false));
// Get a list of all device IDs
List<String> allDeviceIds = groupOneTouchList.map((device) => device.deviceId).toList();
// First call for switch_1
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1', // Controls first switch for all devices
devicesUuid: allDeviceIds,
value: false, // true (on) or false (off) depending on the event value
);
// Check if either response is unsuccessful, then reset to initial state
if (response1['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
emit(FailedState(error: _.toString()));
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
String statusSelected = '';
String optionSelected = '';
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<OneTouchState> emit) async {
try {
emit(LoadingInitialState());
final Map<String, Map<String, String>> controlMap = {
"relay_status": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
"light_mode": {
'Off': 'none',
'On/Off Status': 'relay',
'Switch Position': 'pos',
},
"relay_status_1": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
};
final selectedControl = controlMap[optionSelected]?[statusSelected];
if (selectedControl != null) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: oneTouchId, code: optionSelected, value: selectedControl),
oneTouchId,
);
} else {
debugPrint('Invalid statusSelected or optionSelected');
}
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
}

View File

@ -0,0 +1,148 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
abstract class OneTouchEvent extends Equatable {
const OneTouchEvent();
@override
List<Object> get props => [];
}
class LoadingEvent extends OneTouchEvent {}
class OneTouchUpdated extends OneTouchEvent {}
class InitialEvent extends OneTouchEvent {
final bool groupScreen;
const InitialEvent({required this.groupScreen});
@override
List<Object> get props => [groupScreen];
}
class ChangeFirstSwitchStatusEvent extends OneTouchEvent {
final bool value;
final String deviceId;
const ChangeFirstSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeSecondSwitchStatusEvent extends OneTouchEvent {
final bool value;
final String deviceId;
const ChangeSecondSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class AllOffEvent extends OneTouchEvent {}
class AllOnEvent extends OneTouchEvent {}
class GroupAllOnEvent extends OneTouchEvent {}
class GroupAllOffEvent extends OneTouchEvent {}
class ChangeSlidingSegment extends OneTouchEvent {
final int value;
const ChangeSlidingSegment({required this.value});
@override
List<Object> get props => [value];
}
class GetCounterEvent extends OneTouchEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class SetCounterValue extends OneTouchEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends OneTouchEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends OneTouchEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends OneTouchEvent {}
class OnClose extends OneTouchEvent {}
class InitialWizardEvent extends OneTouchEvent {}
//------------------- Schedule ----------=---------
class GetScheduleEvent extends OneTouchEvent {}
class ScheduleSave extends OneTouchEvent {}
class ToggleScheduleEvent extends OneTouchEvent {
final String id;
final bool toggle;
const ToggleScheduleEvent({required this.toggle, required this.id});
@override
List<Object> get props => [toggle, id];
}
class ToggleDaySelectionEvent extends OneTouchEvent {
final String key;
const ToggleDaySelectionEvent({required this.key});
@override
List<Object> get props => [key];
}
class DeleteScheduleEvent extends OneTouchEvent {
final String id;
const DeleteScheduleEvent({required this.id});
@override
List<Object> get props => [id];
}
class ToggleSelectedEvent extends OneTouchEvent {
final int index;
const ToggleSelectedEvent({required this.index});
@override
List<Object> get props => [index];
}
class ToggleCreateScheduleEvent extends OneTouchEvent {
final int index;
const ToggleCreateScheduleEvent({required this.index});
@override
List<Object> get props => [index];
}
class ChangeFirstWizardSwitchStatusEvent extends OneTouchEvent {
final bool value;
final String deviceId;
const ChangeFirstWizardSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeStatusEvent extends OneTouchEvent {
final String deviceId;
final BuildContext context;
const ChangeStatusEvent({this.deviceId = '',required this.context});
}

View File

@ -0,0 +1,92 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/group_one_touch_model.dart';
import 'package:syncrow_app/features/devices/model/one_touch_model.dart';
class OneTouchState extends Equatable {
const OneTouchState();
@override
List<Object> get props => [];
}
class InitialState extends OneTouchState {}
class LoadingInitialState extends OneTouchState {}
class UpdateState extends OneTouchState {
final OneTouchModel oneTouchModel;
const UpdateState({required this.oneTouchModel});
@override
List<Object> get props => [oneTouchModel];
}
class LoadingNewSate extends OneTouchState {
final OneTouchModel oneTouchModel;
const LoadingNewSate({required this.oneTouchModel});
@override
List<Object> get props => [OneTouchModel];
}
class UpdateGroupState extends OneTouchState {
final List<GroupOneTouchModel> oneTouchList;
final bool allSwitches;
const UpdateGroupState({required this.oneTouchList, required this.allSwitches});
@override
List<Object> get props => [oneTouchList, allSwitches];
}
class FailedState extends OneTouchState {
final String error;
const FailedState({required this.error});
@override
List<Object> get props => [error];
}
class ChangeSlidingSegmentState extends OneTouchState {
final int value;
const ChangeSlidingSegmentState({required this.value});
@override
List<Object> get props => [value];
}
class UpdateTimerState extends OneTouchState {
final int seconds;
const UpdateTimerState({required this.seconds});
@override
List<Object> get props => [seconds];
}
class TimerRunInProgress extends OneTouchState {
final int remainingTime;
const TimerRunInProgress(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class TimerRunComplete extends OneTouchState {}
class SaveSchedule extends OneTouchState {}
class IsToggleState extends OneTouchState {
final bool? onOff;
const IsToggleState({this.onOff});
}
class ChangeTimeState extends OneTouchState {}
class UpdateCreateScheduleState extends OneTouchState {
final bool createSchedule;
UpdateCreateScheduleState(this.createSchedule);
}

View File

@ -0,0 +1,801 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_event.dart';
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_state.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class PowerClampBloc extends Bloc<PowerClampEvent, PowerClampState> {
final String PCId;
PowerClampBloc({
required this.PCId,
}) : super(const PowerClampState()) {
on<PowerClampInitial>(_fetchPowerClampInfo);
// on<ReportLogsInitial>(fetchLogsForLastMonth);
// on<FetchEnergyData>(_mapReportToEnergyData);
on<SelectDateEvent>(checkDayMonthYearSelected);
on<FilterRecordsByDateEvent>(_filterRecordsByDate);
}
DateTime? dateTime = DateTime.now();
String formattedDate = DateFormat('dd/MM/yyyy').format(DateTime.now());
bool lowBattery = false;
bool closingReminder = false;
bool doorAlarm = false;
PowerClampModel deviceStatus = PowerClampModel(
productType: '',
productUuid: '',
status: PowerStatus(
phaseA: Phase(
dataPoints: [
DataPoint(
code: '', customName: '', dpId: 0, time: 0, type: '', value: 0),
],
),
phaseB: Phase(
dataPoints: [
DataPoint(
code: '', customName: '', dpId: 0, time: 0, type: '', value: 0),
],
),
phaseC: Phase(
dataPoints: [
DataPoint(
code: '', customName: '', dpId: 0, time: 0, type: '', value: 0),
],
),
general: Phase(
dataPoints: [
DataPoint(
code: '', customName: '', dpId: 0, time: 0, type: '', value: 0),
],
),
),
);
void _fetchPowerClampInfo(
PowerClampInitial event, Emitter<PowerClampState> emit) async {
emit(PowerClampLoadingState());
try {
var response = await DevicesAPI.getPowerClampStatus(PCId);
PowerClampModel deviceStatus = PowerClampModel.fromJson(response);
emit(UpdateState(powerClampModel: deviceStatus));
} catch (e) {
emit(PowerClampFailedState(errorMessage: e.toString()));
return;
}
}
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
EventDevice recordGroupsDateTime =
EventDevice(code: '', eventTime: DateTime.now(), value: '');
List<EventDevice> record = [
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:13'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:13'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:13'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-11 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-11 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-12 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-13 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-14 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-15 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-16 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-17 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-18 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-19 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-20 11:14:13'),
value: '2284'),
];
List<EventDevice> filteredRecords = [];
int currentIndex = 0;
final List<String> views = ['Day', 'Month', 'Year'];
Widget dateSwitcher() {
void switchView(int direction) {
currentIndex = (currentIndex + direction + views.length) % views.length;
}
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.arrow_left),
onPressed: () {
setState(() {
switchView(-1);
});
},
),
Text(
views[currentIndex],
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
),
IconButton(
icon: const Icon(Icons.arrow_right),
onPressed: () {
setState(() {
switchView(1);
});
},
),
],
);
},
);
}
void checkDayMonthYearSelected(
SelectDateEvent event, Emitter<PowerClampState> emit) async {
emit(PowerClampLoadingState());
if (currentIndex == 0) {
await dayMonthYearPicker(context: event.context).then(
(newDate) {
if (newDate != null) {
dateTime = newDate;
// formattedDate = DateFormat('yyyy/MM/dd').format(dateTime!);
formattedDate = DateFormat('dd/MM/yyyy').format(dateTime!);
add(FilterRecordsByDateEvent(
selectedDate: dateTime!,
viewType: views[currentIndex],
));
}
},
);
} else if (currentIndex == 1) {
await selectMonthAndYear(event.context).then(
(newDate) {
if (newDate != null) {
dateTime = newDate;
formattedDate = DateFormat('yyyy/MM').format(dateTime!);
add(FilterRecordsByDateEvent(
selectedDate: dateTime!,
viewType: views[currentIndex],
));
}
},
);
} else if (currentIndex == 2) {
await selectYear(event.context).then(
(newDate) {
if (newDate != null) {
dateTime = newDate;
formattedDate = DateFormat('yyyy').format(dateTime!);
add(FilterRecordsByDateEvent(
selectedDate: dateTime!,
viewType: views[currentIndex],
));
}
},
);
}
emit(DateSelectedState());
}
Future<DateTime?> selectMonthAndYear(BuildContext context) async {
int selectedYear = DateTime.now().year;
int selectedMonth = DateTime.now().month;
FixedExtentScrollController yearController =
FixedExtentScrollController(initialItem: selectedYear - 1905);
FixedExtentScrollController monthController =
FixedExtentScrollController(initialItem: selectedMonth - 1);
return await showModalBottomSheet<DateTime>(
context: context,
builder: (BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.4,
child: Column(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Select Month and Year',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
const Divider(),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
Expanded(
child: ListWheelScrollView.useDelegate(
controller: yearController,
overAndUnderCenterOpacity: 0.2,
itemExtent: 50,
onSelectedItemChanged: (index) {
selectedYear = 1905 + index;
},
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
(1905 + index).toString(),
style: const TextStyle(fontSize: 18),
),
);
},
childCount: 200,
),
),
),
Expanded(
flex: 2,
child: ListWheelScrollView.useDelegate(
controller: monthController,
overAndUnderCenterOpacity: 0.2,
itemExtent: 50,
onSelectedItemChanged: (index) {
selectedMonth = index + 1;
},
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
DateFormat.MMMM()
.format(DateTime(0, index + 1)),
style: const TextStyle(fontSize: 18),
),
);
},
childCount: 12,
),
),
),
const Spacer(),
],
),
),
const Divider(),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('OK'),
onPressed: () {
final selectedDateTime =
DateTime(selectedYear, selectedMonth);
Navigator.of(context).pop(selectedDateTime);
},
),
],
),
),
],
),
);
},
);
}
Future<DateTime?> selectYear(BuildContext context) async {
int selectedYear = DateTime.now().year;
FixedExtentScrollController yearController =
FixedExtentScrollController(initialItem: selectedYear - 1905);
return await showModalBottomSheet<DateTime>(
context: context,
builder: (BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.4,
child: Column(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Select Year',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
const Divider(),
Expanded(
child: ListWheelScrollView.useDelegate(
controller: yearController,
overAndUnderCenterOpacity: 0.2,
itemExtent: 50,
onSelectedItemChanged: (index) {
selectedYear = 1905 + index;
},
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
(1905 + index).toString(),
style: const TextStyle(fontSize: 18),
),
);
},
childCount: 200,
),
),
),
const Divider(),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context)
.pop(); // Pops without value, returning null
},
),
TextButton(
child: const Text('OK'),
onPressed: () {
final selectedDateTime = DateTime(selectedYear);
Navigator.of(context).pop(
selectedDateTime); // Pops with the selected date
},
),
],
),
),
],
),
);
},
);
}
Future<DateTime?> dayMonthYearPicker({
required BuildContext context,
}) async {
DateTime selectedDate = DateTime.now();
return await showModalBottomSheet<DateTime>(
context: context,
builder: (BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.4,
child: Column(
children: [
Expanded(
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: DateTime.now(),
minimumYear: 1900,
maximumYear: DateTime.now().year,
onDateTimeChanged: (DateTime newDateTime) {
selectedDate = newDateTime;
},
),
),
const Divider(),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop(selectedDate);
},
),
],
),
),
],
),
);
},
);
}
List<EnergyData> energyDataList = [];
void _filterRecordsByDate(
FilterRecordsByDateEvent event, Emitter<PowerClampState> emit) {
emit(PowerClampLoadingState());
if (event.viewType == 'Year') {
filteredRecords = record
.where((record) => record.eventTime!.year == event.selectedDate.year)
.toList();
} else if (event.viewType == 'Month') {
formattedDate =
"${getMonthShortName(event.selectedDate.month)} ${event.selectedDate.year.toString()}";
filteredRecords = record
.where((record) =>
record.eventTime!.year == event.selectedDate.year &&
record.eventTime!.month == event.selectedDate.month)
.toList();
} else if (event.viewType == 'Day') {
filteredRecords = record
.where((record) =>
record.eventTime!.year == event.selectedDate.year &&
record.eventTime!.month == event.selectedDate.month &&
record.eventTime!.day == event.selectedDate.day)
.toList();
}
energyDataList = filteredRecords.map((eventDevice) {
return EnergyData(
event.viewType == 'Year'
? getMonthShortName(
int.tryParse(DateFormat('MM').format(eventDevice.eventTime!))!)
: event.viewType == 'Month'
? DateFormat('dd/MM').format(eventDevice.eventTime!)
: DateFormat('HH:mm:ss').format(eventDevice.eventTime!),
double.parse(eventDevice.value!),
);
}).toList();
selectDateRange();
Future.delayed(const Duration(milliseconds: 500));
emit(FilterRecordsState(filteredRecords: energyDataList));
}
String getMonthShortName(int month) {
final date = DateTime(0, month);
return DateFormat.MMM().format(date);
}
String endChartDate = '';
void selectDateRange() async {
DateTime startDate = dateTime!;
DateTime endDate = DateTime(startDate.year, startDate.month + 1, 1)
.subtract(Duration(days: 1));
String formattedEndDate = DateFormat('dd/MM/yyyy').format(endDate);
endChartDate = ' - $formattedEndDate';
}
}
// _listenToChanges() {
// try {
// DatabaseReference ref =
// FirebaseDatabase.instance.ref('device-status/$PCId');
// Stream<DatabaseEvent> stream = ref.onValue;
// stream.listen((DatabaseEvent event) async {
// if (_timer != null) {
// await Future.delayed(const Duration(seconds: 2));
// }
// Map<dynamic, dynamic> usersMap =
// event.snapshot.value as Map<dynamic, dynamic>;
// List<StatusModel> statusList = [];
// usersMap['status'].forEach((element) {
// statusList.add(StatusModel(code: element['code'], value: true));
// });
// deviceStatus = PowerClampModel.fromJson(statusList);
// if (!isClosed) {
// add(
// PowerClampSwitch(switchD: deviceStatus.doorContactState),
// );
// }
// });
// } catch (_) {}
// }
// New Function: Convert the device report data into EnergyData and emit it.
// void _mapReportToEnergyData(
// FetchEnergyData event, Emitter<PowerClampState> emit) {
// try {
// List<EnergyData> energyDataList = recordGroups.data
// ?.map((event) {
// if (event.code == "VoltageA" && event.eventTime != null) {
// // Convert eventTime to readable format
// DateTime eventDateTime =
// DateTime.fromMillisecondsSinceEpoch(event.eventTime!);
// String formattedTime =
// "${eventDateTime.hour}:${eventDateTime.minute.toString().padLeft(2, '0')} ${eventDateTime.hour >= 12 ? 'PM' : 'AM'}";
// double value = double.tryParse(event.value ?? "0") ?? 0;
// return EnergyData(
// formattedTime, value / 1000); // Assume kWh format
// }
// return null;
// })
// .where((data) => data != null)
// .cast<EnergyData>()
// .toList() ??
// [];
// emit(EnergyDataState(energyData: energyDataList));
// } catch (e) {
// emit(PowerClampFailedState(errorMessage: e.toString()));
// }
// }
// Future<void> selectTimeOfLinePassword(
// SelectDateEvent event, Emitter<PowerClampState> emit) async {
// emit(ChangeTimeState());
// final DateTime? picked = await showDatePicker(
// initialDatePickerMode: DatePickerMode.year,
// context: event.context,
// initialDate: DateTime.now(),
// firstDate: DateTime(1905),
// lastDate: DateTime(2101),
// );
// if (picked != null) {
// final selectedDateTime = DateTime(
// picked.year,
// picked.month,
// picked.day,
// 0,
// 0,
// );
// final selectedTimestamp = DateTime(
// selectedDateTime.year,
// selectedDateTime.month,
// selectedDateTime.day,
// selectedDateTime.hour,
// selectedDateTime.minute,
// ).millisecondsSinceEpoch ~/
// 1000;
// DateTime dateTime = selectedDateTime;
// formattedDate = DateFormat('yyyy/MM/dd').format(dateTime);
// emit(DateSelectedState());
// }
// }
// void _fetchStatus(
// PowerClampInitial event, Emitter<PowerClampState> emit) async {
// emit(PowerClampLoadingState());
// try {
// var response = await DevicesAPI.getDeviceStatus(PCId);
// List<StatusModel> statusModelList = [];
// for (var status in response['status']) {
// statusModelList.add(StatusModel.fromJson(status));
// }
// deviceStatus = PowerClampModel.fromJson(
// statusModelList,
// );
// emit(UpdateState(powerClampModel: deviceStatus));
// Future.delayed(const Duration(milliseconds: 500));
// // _listenToChanges();
// } catch (e) {
// emit(PowerClampFailedState(errorMessage: e.toString()));
// return;
// }
// }
// Future<void> fetchLogsForLastMonth(
// ReportLogsInitial event, Emitter<PowerClampState> emit) async {
// DateTime now = DateTime.now();
// DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
// int startTime = lastMonth.millisecondsSinceEpoch;
// int endTime = now.millisecondsSinceEpoch;
// try {
// emit(PowerClampLoadingState());
// var response = await DevicesAPI.getReportLogs(
// startTime: startTime.toString(),
// endTime: endTime.toString(),
// deviceUuid: PCId,
// code: event.code!,
// );
// recordGroups = response;
// record = recordGroups.data!.map((event) {
// return EventDevice(
// code: event.code,
// eventTime: event.eventTime != null
// ? DateTime.fromMillisecondsSinceEpoch(event.eventTime!)
// : null,
// value: event.value,
// );
// }).toList();
// for (var event in record) {
// print(
// 'Code: ${event.code}, Event Time: ${DateFormat('yyyy-MM-dd hh:mm:ss a').format(event.eventTime!)}, Value: ${event.value}');
// }
// emit(UpdateState(powerClampModel: deviceStatus));
// } on DioException catch (e) {
// final errorData = e.response!.data;
// String errorMessage = errorData['message'];
// }
// }
// int transformTimestamp(int originalTime) {
// DateTime originalDateTime =
// DateTime.fromMillisecondsSinceEpoch(originalTime);
// DateTime transformedDateTime = originalDateTime.add(Duration(hours: 1));
// return transformedDateTime.millisecondsSinceEpoch;
// }
// void addDataToRecord(List<Map<String, dynamic>> rawData) {
// for (var dataPoint in rawData) {
// EventDevice event = EventDevice.fromJson(dataPoint);
// record.add(event);
// }
// }

View File

@ -0,0 +1,119 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
abstract class PowerClampEvent extends Equatable {
const PowerClampEvent();
@override
List<Object> get props => [];
}
class PowerClampLoading extends PowerClampEvent {}
class PowerClampSwitch extends PowerClampEvent {
final bool switchD;
final String deviceId;
final String productId;
const PowerClampSwitch(
{required this.switchD, this.deviceId = '', this.productId = ''});
@override
List<Object> get props => [switchD, deviceId, productId];
}
class PowerClampUpdated extends PowerClampEvent {}
class FetchEnergyData extends PowerClampEvent {}
class SelectDateEvent extends PowerClampEvent {
BuildContext context;
SelectDateEvent({required this.context});
}
class PowerClampInitial extends PowerClampEvent {
const PowerClampInitial();
}
class ReportLogsInitial extends PowerClampEvent {
final String? code;
const ReportLogsInitial({required this.code});
@override
List<Object> get props => [code!];
}
class PowerClampChangeStatus extends PowerClampEvent {}
class GetCounterEvent extends PowerClampEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class ToggleLowBatteryEvent extends PowerClampEvent {
final bool isLowBatteryEnabled;
const ToggleLowBatteryEvent(this.isLowBatteryEnabled);
@override
List<Object> get props => [isLowBatteryEnabled];
}
class ToggleClosingReminderEvent extends PowerClampEvent {
final bool isClosingReminderEnabled;
const ToggleClosingReminderEvent(this.isClosingReminderEnabled);
@override
List<Object> get props => [isClosingReminderEnabled];
}
class ToggleDoorAlarmEvent extends PowerClampEvent {
final bool isDoorAlarmEnabled;
const ToggleDoorAlarmEvent(this.isDoorAlarmEnabled);
@override
List<Object> get props => [isDoorAlarmEnabled];
}
class SetCounterValue extends PowerClampEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends PowerClampEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends PowerClampEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends PowerClampEvent {}
class OnClose extends PowerClampEvent {}
class FilterRecordsByDateEvent extends PowerClampEvent {
final DateTime selectedDate;
final String viewType; // 'Day', 'Month', 'Year'
const FilterRecordsByDateEvent(
{required this.selectedDate, required this.viewType});
}

View File

@ -0,0 +1,57 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
class PowerClampState extends Equatable {
const PowerClampState();
@override
List<Object> get props => [];
}
class PowerClampInitialState extends PowerClampState {}
class PowerClampLoadingState extends PowerClampState {}
class ChangeTimeState extends PowerClampState {}
class DateSelectedState extends PowerClampState {}
//DateSelectedState
class PowerClampFailedState extends PowerClampState {
final String errorMessage;
const PowerClampFailedState({required this.errorMessage});
@override
List<Object> get props => [errorMessage];
}
class UpdateState extends PowerClampState {
final PowerClampModel powerClampModel;
const UpdateState({required this.powerClampModel});
@override
List<Object> get props => [powerClampModel];
}
class LoadingNewSate extends PowerClampState {
final PowerClampModel powerClampModel;
const LoadingNewSate({required this.powerClampModel});
@override
List<Object> get props => [powerClampModel];
}
class EnergyDataState extends PowerClampState {
final List<EnergyData> energyData;
const EnergyDataState({required this.energyData});
}
// State for filtered records
class FilterRecordsState extends PowerClampState {
final List<EnergyData> filteredRecords;
const FilterRecordsState({required this.filteredRecords});
}

View File

@ -102,7 +102,7 @@ class SmartDoorBloc extends Bloc<SmartDoorEvent, SmartDoorState> {
}
deviceStatus = SmartDoorModel.fromJson(statusModelList);
emit(UpdateState(smartDoorModel: deviceStatus));
_listenToChanges();
// _listenToChanges();
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
return;

View File

@ -25,9 +25,6 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
secondCountDown: 0,
thirdCountDown: 0);
Timer? _timer;
// Timer? _firstSwitchTimer;
// Timer? _secondSwitchTimer;
// Timer? _thirdSwitchTimer;
bool threeGangGroup = false;
List<DeviceModel> devicesList = [];
@ -104,7 +101,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
deviceStatus = ThreeGangModel.fromJson(statusModelList);
emit(UpdateState(threeGangModel: deviceStatus));
_listenToChanges();
// _listenToChanges();
}
} catch (e) {
emit(FailedState(error: e.toString()));
@ -163,7 +160,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 500), () async {
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangGroup ? event.deviceId : threeGangId,
@ -203,7 +200,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 500), () async {
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangGroup ? event.deviceId : threeGangId,
@ -243,7 +240,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 500), () async {
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeGangGroup ? event.deviceId : threeGangId,
@ -338,27 +335,29 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: true));
for (int i = 0; i < groupThreeGangList.length; i++) {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_1', value: true),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_2', value: true),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_3', value: true),
groupThreeGangList[i].deviceId),
]);
List<String> allDeviceIds = groupThreeGangList.map((device) => device.deviceId).toList();
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
break;
}
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: true,
);
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: true,
);
final response3 = await DevicesAPI.deviceBatchController(
code: 'switch_3',
devicesUuid: allDeviceIds,
value: true,
);
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]' ||
response3['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
@ -375,28 +374,29 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
groupThreeGangList[i].thirdSwitch = false;
}
emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: false));
List<String> allDeviceIds = groupThreeGangList.map((device) => device.deviceId).toList();
for (int i = 0; i < groupThreeGangList.length; i++) {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_1', value: false),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_2', value: false),
groupThreeGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupThreeGangList[i].deviceId, code: 'switch_3', value: false),
groupThreeGangList[i].deviceId),
]);
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: false,
);
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: false,
);
final response3 = await DevicesAPI.deviceBatchController(
code: 'switch_3',
devicesUuid: allDeviceIds,
value: false,
);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
break;
}
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]' ||
response3['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
@ -531,7 +531,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
CustomSnackBar.displaySnackBar('Save Successfully');
add(GetScheduleEvent());
emit(ThreeGangSaveSchedule());
add(const ToggleCreateScheduleEvent(index:1 ));
add(const ToggleCreateScheduleEvent(index: 1));
} else {
CustomSnackBar.displaySnackBar('Please select days');
}
@ -606,38 +606,19 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
}
}
// void toggleCreateSchedule() {
// emit(LoadingInitialState());
// createSchedule = !createSchedule;
// selectedDays.clear();
// selectedTime = DateTime.now();
// emit(UpdateCreateScheduleState(createSchedule));
// emit(ChangeSlidingSegmentState(value: 1));
// }
// void toggleSelectedIndex(index) {
// emit(LoadingInitialState());
// selectedTabIndex = index;
// emit(ChangeSlidingSegmentState(value: selectedTabIndex));
// }
void toggleSelectedIndex( ToggleSelectedEvent event, Emitter<ThreeGangState> emit) {
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<ThreeGangState> emit) {
emit(LoadingInitialState());
selectedTabIndex =event.index;
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
int selectedTabIndex = 0;
bool toggleSchedule = true;

View File

@ -135,4 +135,6 @@ class ToggleCreateScheduleEvent extends ThreeGangEvent {
const ToggleCreateScheduleEvent({required this.index});
@override
List<Object> get props => [index];
}
}
class InitialWizardDevises extends ThreeGangEvent {}

View File

@ -0,0 +1,682 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/three_touch_bloc/three_touch_event.dart';
import 'package:syncrow_app/features/devices/bloc/three_touch_bloc/three_touch_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/group_three_touch_model.dart';
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/three_touch_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class ThreeTouchBloc extends Bloc<ThreeTouchEvent, ThreeTouchState> {
final String threeTouchId;
final String switchCode;
ThreeTouchModel deviceStatus = ThreeTouchModel(
firstSwitch: false,
secondSwitch: false,
thirdSwitch: false,
firstCountDown: 0,
secondCountDown: 0,
thirdCountDown: 0,
light_mode: lightStatus.off,
relay: status.off,
relay_status_1: status.off,
relay_status_2: status.off,
relay_status_3: status.off,
);
Timer? _timer;
bool threeTouchGroup = false;
List<DeviceModel> devicesList = [];
List<GroupThreeTouchModel> groupThreeTouchList = [];
bool allSwitchesOn = true;
ThreeTouchBloc({required this.threeTouchId, required this.switchCode}) : super(InitialState()) {
on<InitialEvent>(_fetchThreeTouchStatus);
on<ThreeTouchUpdated>(_threeTouchUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
on<ChangeSecondSwitchStatusEvent>(_changeSecondSwitch);
on<ChangeThirdSwitchStatusEvent>(_changeThirdSwitch);
on<AllOffEvent>(_allOff);
on<AllOnEvent>(_allOn);
on<ChangeSlidingSegment>(_changeSliding);
on<SetCounterValue>(_setCounterValue);
on<GetCounterEvent>(_getCounterValue);
on<TickTimer>(_onTickTimer);
on<OnClose>(_onClose);
on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff);
on<ToggleDaySelectionEvent>(toggleDaySelection);
on<ThreeTouchSave>(saveSchedule);
on<GetScheduleEvent>(getSchedule);
on<ToggleScheduleEvent>(toggleChange);
on<DeleteScheduleEvent>(deleteSchedule);
on<ToggleSelectedEvent>(toggleSelectedIndex);
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
on<ChangeStatusEvent>(_changeStatus);
}
void _fetchThreeTouchStatus(InitialEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingInitialState());
try {
threeTouchGroup = event.groupScreen;
if (threeTouchGroup) {
devicesList = [];
groupThreeTouchList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', '3GT');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = ThreeTouchModel.fromJson(statusModelList);
groupThreeTouchList.add(GroupThreeTouchModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
secondSwitch: deviceStatus.secondSwitch,
thirdSwitch: deviceStatus.thirdSwitch));
}
if (groupThreeTouchList.isNotEmpty) {
groupThreeTouchList.firstWhere((element) {
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesOn));
} else {
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = ThreeTouchModel.fromJson(statusModelList);
emit(UpdateState(threeTouchModel: deviceStatus));
// _listenToChanges();
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeTouchId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = ThreeTouchModel.fromJson(statusList);
if (!isClosed) {
add(ThreeTouchUpdated());
}
});
} catch (_) {}
}
_threeTouchUpdated(ThreeTouchUpdated event, Emitter<ThreeTouchState> emit) {
emit(UpdateState(threeTouchModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
if (threeTouchGroup) {
bool allSwitchesValue = true;
groupThreeTouchList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
} else {
deviceStatus.firstSwitch = !event.value;
emit(UpdateState(threeTouchModel: deviceStatus));
}
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchGroup ? event.deviceId : threeTouchId,
code: 'switch_1',
value: !event.value),
threeTouchGroup ? event.deviceId : threeTouchId);
if (!response['success']) {
add(InitialEvent(groupScreen: threeTouchGroup));
}
});
} catch (_) {
add(InitialEvent(groupScreen: threeTouchGroup));
}
}
void _changeSecondSwitch(
ChangeSecondSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
if (threeTouchGroup) {
bool allSwitchesValue = true;
groupThreeTouchList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.secondSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
} else {
deviceStatus.secondSwitch = !event.value;
emit(UpdateState(threeTouchModel: deviceStatus));
}
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchGroup ? event.deviceId : threeTouchId,
code: 'switch_2',
value: !event.value),
threeTouchGroup ? event.deviceId : threeTouchId);
if (!response['success']) {
add(InitialEvent(groupScreen: threeTouchGroup));
}
});
} catch (_) {
add(InitialEvent(groupScreen: threeTouchGroup));
}
}
void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
if (threeTouchGroup) {
bool allSwitchesValue = true;
groupThreeTouchList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.thirdSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: allSwitchesValue));
} else {
deviceStatus.thirdSwitch = !event.value;
emit(UpdateState(threeTouchModel: deviceStatus));
}
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchGroup ? event.deviceId : threeTouchId,
code: 'switch_3',
value: !event.value),
threeTouchGroup ? event.deviceId : threeTouchId);
if (!response['success']) {
add(InitialEvent(groupScreen: threeTouchGroup));
}
});
} catch (_) {
add(InitialEvent(groupScreen: threeTouchGroup));
}
}
void _allOff(AllOffEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
deviceStatus.firstSwitch = false;
deviceStatus.secondSwitch = false;
deviceStatus.thirdSwitch = false;
emit(UpdateState(threeTouchModel: deviceStatus));
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_3', value: deviceStatus.thirdSwitch),
threeTouchId),
]);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
}
}
void _allOn(AllOnEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
deviceStatus.firstSwitch = true;
deviceStatus.secondSwitch = true;
deviceStatus.thirdSwitch = true;
emit(UpdateState(threeTouchModel: deviceStatus));
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
threeTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: threeTouchId, code: 'switch_3', value: deviceStatus.thirdSwitch),
threeTouchId),
]);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
for (int i = 0; i < groupThreeTouchList.length; i++) {
groupThreeTouchList[i].firstSwitch = true;
groupThreeTouchList[i].secondSwitch = true;
groupThreeTouchList[i].thirdSwitch = true;
}
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: true));
List<String> allDeviceIds = groupThreeTouchList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: true,
);
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: true,
);
final response3 = await DevicesAPI.deviceBatchController(
code: 'switch_3',
devicesUuid: allDeviceIds,
value: true,
);
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]' ||
response3['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
try {
for (int i = 0; i < groupThreeTouchList.length; i++) {
groupThreeTouchList[i].firstSwitch = false;
groupThreeTouchList[i].secondSwitch = false;
groupThreeTouchList[i].thirdSwitch = false;
}
List<String> allDeviceIds = groupThreeTouchList.map((device) => device.deviceId).toList();
emit(UpdateGroupState(threeTouchList: groupThreeTouchList, allSwitches: false));
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: false,
);
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: false,
);
final response3 = await DevicesAPI.deviceBatchController(
code: 'switch_3',
devicesUuid: allDeviceIds,
value: false,
);
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]' ||
response3['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<ThreeTouchState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<ThreeTouchState> emit) async {
emit(LoadingNewSate(threeTouchModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeTouchId, code: event.deviceCode, value: seconds),
threeTouchId);
if (response['success'] ?? false) {
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown = seconds;
} else if (event.deviceCode == 'countdown_2') {
deviceStatus.secondCountDown = seconds;
} else if (event.deviceCode == 'countdown_3') {
deviceStatus.thirdCountDown = seconds;
}
} else {
emit(const FailedState(error: 'Something went wrong'));
return;
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
if (seconds > 0) {
_onStartTimer(seconds);
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
void _getCounterValue(GetCounterEvent event, Emitter<ThreeTouchState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(threeTouchId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = ThreeTouchModel.fromJson(statusModelList);
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown > 0
? _onStartTimer(deviceStatus.firstCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
} else if (event.deviceCode == 'countdown_2') {
deviceStatus.secondCountDown > 0
? _onStartTimer(deviceStatus.secondCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.secondCountDown));
} else if (event.deviceCode == 'countdown_3') {
deviceStatus.thirdCountDown > 0
? _onStartTimer(deviceStatus.thirdCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.thirdCountDown));
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _onClose(OnClose event, Emitter<ThreeTouchState> emit) {
_timer?.cancel();
}
void _onStartTimer(int seconds) {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
add(TickTimer(seconds - timer.tick));
});
}
void _onTickTimer(TickTimer event, Emitter<ThreeTouchState> emit) {
if (event.remainingTime > 0) {
emit(TimerRunInProgress(event.remainingTime));
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
List<Map<String, String>> days = [
{"day": "Sun", "key": "Sun"},
{"day": "Mon", "key": "Mon"},
{"day": "Tue", "key": "Tue"},
{"day": "Wed", "key": "Wed"},
{"day": "Thu", "key": "Thu"},
{"day": "Fri", "key": "Fri"},
{"day": "Sat", "key": "Sat"},
];
Future<void> toggleDaySelection(
ToggleDaySelectionEvent event,
Emitter<ThreeTouchState> emit,
) async {
emit(LoadingInitialState());
if (selectedDays.contains(event.key)) {
selectedDays.remove(event.key);
} else {
selectedDays.add(event.key);
}
emit(ChangeTimeState());
add(ChangeSlidingSegment(value: 1));
}
Future<void> saveSchedule(
ThreeTouchSave event,
Emitter<ThreeTouchState> emit,
) async {
try {
if (selectedDays.isNotEmpty) {
emit(LoadingInitialState());
await DevicesAPI.postSchedule(
category: switchCode,
deviceId: threeTouchId,
time: getTimeStampWithoutSeconds(selectedTime).toString(),
code: switchCode,
value: toggleSchedule,
days: selectedDays);
CustomSnackBar.displaySnackBar('Save Successfully');
add(GetScheduleEvent());
emit(ThreeTouchSaveSchedule());
add(const ToggleCreateScheduleEvent(index: 1));
} else {
CustomSnackBar.displaySnackBar('Please select days');
}
} catch (e) {
emit(FailedState(error: e.toString()));
}
}
Future<void> getSchedule(
GetScheduleEvent event,
Emitter<ThreeTouchState> emit,
) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.getSchedule(
category: switchCode,
deviceId: threeTouchId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(ToggleScheduleEvent event, Emitter<ThreeTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
scheduleId: event.id, deviceUuid: threeTouchId, enable: event.toggle);
if (response == true) {
add(GetScheduleEvent());
toggleSchedule = event.toggle;
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
add(const ChangeSlidingSegment(value: 1));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<ThreeTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id,
deviceUuid: threeTouchId,
);
if (response == true) {
add(GetScheduleEvent());
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
add(const ChangeSlidingSegment(value: 1));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<ThreeTouchState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeTouchState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
int selectedTabIndex = 0;
bool toggleSchedule = true;
List<String> selectedDays = [];
bool createSchedule = false;
List<ScheduleModel> listSchedule = [];
DateTime? selectedTime = DateTime.now();
String statusSelected = '';
String optionSelected = '';
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<ThreeTouchState> emit) async {
try {
emit(LoadingInitialState());
final Map<String, Map<String, String>> controlMap = {
"relay_status": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
"light_mode": {
'Off': 'none',
'On/Off Status': 'relay',
'Switch Position': 'pos',
},
"relay_status_1": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
"relay_status_2": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
"relay_status_3": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
};
final selectedControl = controlMap[optionSelected]?[statusSelected];
if (selectedControl != null) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeTouchId, code: optionSelected, value: selectedControl),
threeTouchId,
);
} else {
emit(const FailedState(error: 'Invalid statusSelected or optionSelected'));
}
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
}

View File

@ -0,0 +1,147 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
abstract class ThreeTouchEvent extends Equatable {
const ThreeTouchEvent();
@override
List<Object> get props => [];
}
class LoadingEvent extends ThreeTouchEvent {}
class ThreeTouchUpdated extends ThreeTouchEvent {}
class InitialEvent extends ThreeTouchEvent {
final bool groupScreen;
const InitialEvent({required this.groupScreen});
@override
List<Object> get props => [groupScreen];
}
class ChangeFirstSwitchStatusEvent extends ThreeTouchEvent {
final bool value;
final String deviceId;
const ChangeFirstSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeSecondSwitchStatusEvent extends ThreeTouchEvent {
final bool value;
final String deviceId;
const ChangeSecondSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeThirdSwitchStatusEvent extends ThreeTouchEvent {
final bool value;
final String deviceId;
const ChangeThirdSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class AllOffEvent extends ThreeTouchEvent {}
class AllOnEvent extends ThreeTouchEvent {}
class GroupAllOnEvent extends ThreeTouchEvent {}
class GroupAllOffEvent extends ThreeTouchEvent {}
class ChangeSlidingSegment extends ThreeTouchEvent {
final int value;
const ChangeSlidingSegment({required this.value});
@override
List<Object> get props => [value];
}
class GetCounterEvent extends ThreeTouchEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class SetCounterValue extends ThreeTouchEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends ThreeTouchEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends ThreeTouchEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends ThreeTouchEvent {}
class OnClose extends ThreeTouchEvent {}
//------------------- Schedule ----------=---------
class GetScheduleEvent extends ThreeTouchEvent {}
class ThreeTouchSave extends ThreeTouchEvent {}
class ToggleScheduleEvent extends ThreeTouchEvent {
final String id;
final bool toggle;
const ToggleScheduleEvent({required this.toggle, required this.id});
@override
List<Object> get props => [toggle, id];
}
class ToggleDaySelectionEvent extends ThreeTouchEvent {
final String key;
const ToggleDaySelectionEvent({required this.key});
@override
List<Object> get props => [key];
}
class DeleteScheduleEvent extends ThreeTouchEvent {
final String id;
const DeleteScheduleEvent({required this.id});
@override
List<Object> get props => [id];
}
class ToggleSelectedEvent extends ThreeTouchEvent {
final int index;
const ToggleSelectedEvent({required this.index});
@override
List<Object> get props => [index];
}
class ToggleCreateScheduleEvent extends ThreeTouchEvent {
final int index;
const ToggleCreateScheduleEvent({required this.index});
@override
List<Object> get props => [index];
}
class InitialWizardDevises extends ThreeTouchEvent {}
class ChangeStatusEvent extends ThreeTouchEvent {
final String deviceId;
final BuildContext context;
const ChangeStatusEvent({this.deviceId = '', required this.context});
}

View File

@ -0,0 +1,96 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/group_three_touch_model.dart';
import 'package:syncrow_app/features/devices/model/three_touch_model.dart';
class ThreeTouchState extends Equatable {
const ThreeTouchState();
@override
List<Object> get props => [];
}
class InitialState extends ThreeTouchState {}
class LoadingInitialState extends ThreeTouchState {}
class UpdateState extends ThreeTouchState {
final ThreeTouchModel threeTouchModel;
const UpdateState({required this.threeTouchModel});
@override
List<Object> get props => [threeTouchModel];
}
class LoadingNewSate extends ThreeTouchState {
final ThreeTouchModel threeTouchModel;
const LoadingNewSate({required this.threeTouchModel});
@override
List<Object> get props => [threeTouchModel];
}
class UpdateGroupState extends ThreeTouchState {
final List<GroupThreeTouchModel> threeTouchList;
final bool allSwitches;
const UpdateGroupState(
{required this.threeTouchList, required this.allSwitches});
@override
List<Object> get props => [threeTouchList, allSwitches];
}
class FailedState extends ThreeTouchState {
final String error;
const FailedState({required this.error});
@override
List<Object> get props => [error];
}
class ChangeSlidingSegmentState extends ThreeTouchState {
final int value;
const ChangeSlidingSegmentState({required this.value});
@override
List<Object> get props => [value];
}
class UpdateTimerState extends ThreeTouchState {
final int seconds;
const UpdateTimerState({required this.seconds});
@override
List<Object> get props => [seconds];
}
class TimerRunInProgress extends ThreeTouchState {
final int remainingTime;
const TimerRunInProgress(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class TimerRunComplete extends ThreeTouchState {}
class ThreeTouchSaveSchedule extends ThreeTouchState {}
class IsToggleState extends ThreeTouchState {
final bool? onOff;
const IsToggleState({this.onOff});
}
class ChangeTimeState extends ThreeTouchState {}
class UpdateCreateScheduleState extends ThreeTouchState {
final bool createSchedule;
UpdateCreateScheduleState(this.createSchedule);
}
class ChangeStateSetting extends ThreeTouchState {
const ChangeStateSetting();
}

View File

@ -35,8 +35,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
bool createSchedule = false;
List<ScheduleModel> listSchedule = [];
TwoGangBloc({required this.twoGangId, required this.switchCode})
: super(InitialState()) {
TwoGangBloc({required this.twoGangId, required this.switchCode}) : super(InitialState()) {
on<InitialEvent>(_fetchTwoGangStatus);
on<TwoGangUpdated>(_twoGangUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
@ -57,36 +56,22 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
on<DeleteScheduleEvent>(deleteSchedule);
on<ToggleSelectedEvent>(toggleSelectedIndex);
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
on<InitialWizardEvent>(_fetchTwoGangWizardStatus);
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<ChangeSecondWizardSwitchStatusEvent>(_changeSecondWizardSwitch);
}
DateTime? selectedTime = DateTime.now();
// void toggleCreateSchedule() {
// emit(LoadingInitialState());
// createSchedule = !createSchedule;
// selectedDays.clear();
// selectedTime = DateTime.now();
// emit(UpdateCreateScheduleState(createSchedule));
// emit(ChangeSlidingSegmentState(value: 1));
// }
int selectedTabIndex = 0;
// void toggleSelectedIndex(index) {
// emit(LoadingInitialState());
// selectedTabIndex = index;
// emit(ChangeSlidingSegmentState(value: selectedTabIndex));
// }
void toggleSelectedIndex(
ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(
ToggleCreateScheduleEvent event, Emitter<TwoGangState> emit) {
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<TwoGangState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
@ -94,55 +79,17 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
emit(UpdateCreateScheduleState(createSchedule));
}
void _fetchTwoGangStatus(
InitialEvent event, Emitter<TwoGangState> emit) async {
void _fetchTwoGangStatus(InitialEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingInitialState());
try {
twoGangGroup = event.groupScreen;
if (twoGangGroup) {
devicesList = [];
groupTwoGangList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
for (int i = 0; i < devicesList.length; i++) {
var response =
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = TwoGangModel.fromJson(statusModelList);
groupTwoGangList.add(GroupTwoGangModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
secondSwitch: deviceStatus.secondSwitch,
));
}
if (groupTwoGangList.isNotEmpty) {
groupTwoGangList.firstWhere((element) {
if (!element.firstSwitch || !element.secondSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(
twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
} else {
var response = await DevicesAPI.getDeviceStatus(twoGangId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = TwoGangModel.fromJson(statusModelList);
emit(UpdateState(twoGangModel: deviceStatus));
_listenToChanges();
var response = await DevicesAPI.getDeviceStatus(twoGangId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = TwoGangModel.fromJson(statusModelList);
emit(UpdateState(twoGangModel: deviceStatus));
// _listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
@ -151,21 +98,18 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
_listenToChanges() {
try {
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$twoGangId');
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoGangId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList
.add(StatusModel(code: element['code'], value: element['value']));
statusList.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = TwoGangModel.fromJson(statusList);
@ -180,8 +124,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
emit(UpdateState(twoGangModel: deviceStatus));
}
void _changeFirstSwitch(
ChangeFirstSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
deviceStatus.firstSwitch = !event.value;
@ -190,25 +133,21 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 500), () async {
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangGroup ? event.deviceId : twoGangId,
code: 'switch_1',
value: !event.value),
twoGangGroup ? event.deviceId : twoGangId);
DeviceControlModel(deviceId: twoGangId, code: 'switch_1', value: !event.value),
twoGangId);
if (!response['success']) {
add(InitialEvent(groupScreen: twoGangGroup));
add(const InitialEvent());
}
});
} catch (_) {
add(InitialEvent(groupScreen: twoGangGroup));
add(const InitialEvent());
}
}
void _changeSecondSwitch(
ChangeSecondSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
deviceStatus.secondSwitch = !event.value;
@ -216,20 +155,17 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 500), () async {
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangGroup ? event.deviceId : twoGangId,
code: 'switch_2',
value: !event.value),
twoGangGroup ? event.deviceId : twoGangId);
DeviceControlModel(deviceId: twoGangId, code: 'switch_2', value: !event.value),
twoGangId);
if (!response['success']) {
add(InitialEvent(groupScreen: twoGangGroup));
add(const InitialEvent());
}
});
} catch (_) {
add(InitialEvent(groupScreen: twoGangGroup));
add(const InitialEvent());
}
}
@ -244,25 +180,21 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
twoGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
twoGangId),
]);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
add(const InitialEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
add(const InitialEvent());
}
}
@ -275,24 +207,20 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId,
code: 'switch_1',
value: deviceStatus.firstSwitch),
deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
twoGangId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId,
code: 'switch_2',
value: deviceStatus.secondSwitch),
deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
twoGangId),
]);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
add(const InitialEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: false));
add(const InitialEvent());
}
}
@ -304,32 +232,28 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
groupTwoGangList[i].secondSwitch = true;
}
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: true));
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
for (int i = 0; i < groupTwoGangList.length; i++) {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId,
code: 'switch_1',
value: true),
groupTwoGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId,
code: 'switch_2',
value: true),
groupTwoGangList[i].deviceId),
]);
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: true,
);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
break;
}
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: true,
);
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
add(InitialWizardEvent());
}
}
@ -340,50 +264,45 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
groupTwoGangList[i].firstSwitch = false;
groupTwoGangList[i].secondSwitch = false;
}
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: false));
for (int i = 0; i < groupTwoGangList.length; i++) {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId,
code: 'switch_1',
value: false),
groupTwoGangList[i].deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId,
code: 'switch_2',
value: false),
groupTwoGangList[i].deviceId),
]);
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
break;
}
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: false,
);
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: false,
);
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent(groupScreen: true));
add(InitialWizardEvent());
}
}
void _changeSliding(
ChangeSlidingSegment event, Emitter<TwoGangState> emit) async {
void _changeSliding(ChangeSlidingSegment event, Emitter<TwoGangState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(
SetCounterValue event, Emitter<TwoGangState> emit) async {
void _setCounterValue(SetCounterValue event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoGangId, code: event.deviceCode, value: seconds),
DeviceControlModel(deviceId: twoGangId, code: event.deviceCode, value: seconds),
twoGangId);
if (response['success'] ?? false) {
@ -408,8 +327,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
void _getCounterValue(
GetCounterEvent event, Emitter<TwoGangState> emit) async {
void _getCounterValue(GetCounterEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingInitialState());
try {
add(GetScheduleEvent());
@ -476,7 +394,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
selectedDays.add(event.key);
}
emit(ChangeTimeState());
add(ChangeSlidingSegment(value: 1));
add(const ChangeSlidingSegment(value: 1));
}
Future<void> saveSchedule(
@ -486,7 +404,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
try {
if (selectedDays.isNotEmpty) {
emit(LoadingInitialState());
final response = await DevicesAPI.postSchedule(
await DevicesAPI.postSchedule(
category: switchCode,
deviceId: twoGangId,
time: getTimeStampWithoutSeconds(selectedTime).toString(),
@ -517,8 +435,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
deviceId: twoGangId,
);
List<dynamic> jsonData = response;
listSchedule =
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
@ -529,13 +446,12 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleRepeat(
ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
Future toggleRepeat(ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
@ -554,8 +470,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
}
}
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
Future deleteSchedule(DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
@ -574,4 +489,106 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
emit(FailedState(error: errorMessage.toString()));
}
}
void _fetchTwoGangWizardStatus(InitialWizardEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
groupTwoGangList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = TwoGangModel.fromJson(statusModelList);
groupTwoGangList.add(GroupTwoGangModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
secondSwitch: deviceStatus.secondSwitch,
));
}
if (groupTwoGangList.isNotEmpty) {
groupTwoGangList.firstWhere((element) {
if (!element.firstSwitch || !element.secondSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
bool allSwitchesValue = true;
groupTwoGangList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: !event.value,
);
if (response['failedResults'].toString() != '[]') {
add(InitialWizardEvent());
}
} catch (_) {
add(InitialWizardEvent());
}
}
void _changeSecondWizardSwitch(
ChangeSecondWizardSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus));
try {
bool allSwitchesValue = true;
groupTwoGangList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.secondSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch) {
allSwitchesValue = false;
}
});
List<String> allDeviceIds = groupTwoGangList.map((device) => device.deviceId).toList();
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: !event.value,
);
if (response['failedResults'].toString() != '[]') {
add(InitialWizardEvent());
}
} catch (_) {
add(InitialWizardEvent());
}
}
}

View File

@ -10,17 +10,20 @@ abstract class TwoGangEvent extends Equatable {
class LoadingEvent extends TwoGangEvent {}
class TwoGangUpdated extends TwoGangEvent {}
class TwoGangSave extends TwoGangEvent {}
class ToggleScheduleEvent extends TwoGangEvent {
final String id;
final bool toggle;
const ToggleScheduleEvent({required this.toggle,required this.id});
const ToggleScheduleEvent({required this.toggle, required this.id});
@override
List<Object> get props => [toggle,id];
List<Object> get props => [toggle, id];
}
class errorMessage extends TwoGangEvent {}
class ToggleDaySelectionEvent extends TwoGangEvent {
class errorMessage extends TwoGangEvent {}
class ToggleDaySelectionEvent extends TwoGangEvent {
final String key;
const ToggleDaySelectionEvent({required this.key});
@ -29,10 +32,9 @@ class ToggleDaySelectionEvent extends TwoGangEvent {
}
class InitialEvent extends TwoGangEvent {
final bool groupScreen;
const InitialEvent({required this.groupScreen});
const InitialEvent();
@override
List<Object> get props => [groupScreen];
List<Object> get props => [];
}
class ChangeFirstSwitchStatusEvent extends TwoGangEvent {
@ -51,7 +53,6 @@ class ChangeSecondSwitchStatusEvent extends TwoGangEvent {
List<Object> get props => [value, deviceId];
}
class AllOffEvent extends TwoGangEvent {}
class AllOnEvent extends TwoGangEvent {}
@ -60,13 +61,9 @@ class GroupAllOnEvent extends TwoGangEvent {}
class GroupAllOffEvent extends TwoGangEvent {}
// two_gang_event.dart
// class ToggleCreateScheduleEvent extends TwoGangEvent {}
class ChangeSlidingSegment extends TwoGangEvent {
final int value;
const ChangeSlidingSegment({required this.value});
@ -111,20 +108,20 @@ class StopTimer extends TwoGangEvent {}
class OnClose extends TwoGangEvent {}
class GetScheduleEvent extends TwoGangEvent {}
class DeleteScheduleEvent extends TwoGangEvent {
final String id;
const DeleteScheduleEvent({required this.id});
@override
List<Object> get props => [id];
}
class TabChangedEvent extends TwoGangEvent {
final int index;
TabChangedEvent({required this.index});
}
class ToggleSelectedEvent extends TwoGangEvent {
final int index;
const ToggleSelectedEvent({required this.index});
@ -132,7 +129,6 @@ class ToggleSelectedEvent extends TwoGangEvent {
List<Object> get props => [index];
}
class ToggleCreateScheduleEvent extends TwoGangEvent {
final int index;
const ToggleCreateScheduleEvent({required this.index});
@ -140,5 +136,20 @@ class ToggleCreateScheduleEvent extends TwoGangEvent {
List<Object> get props => [index];
}
class InitialWizardEvent extends TwoGangEvent {}
class ChangeFirstWizardSwitchStatusEvent extends TwoGangEvent {
final bool value;
final String deviceId;
const ChangeFirstWizardSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeSecondWizardSwitchStatusEvent extends TwoGangEvent {
final bool value;
final String deviceId;
const ChangeSecondWizardSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}

View File

@ -0,0 +1,642 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/two_touch_bloc/two_touch_event.dart';
import 'package:syncrow_app/features/devices/bloc/two_touch_bloc/two_touch_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/group_two_touch_model.dart';
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/two_touch_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
final String twoTouchId;
final String switchCode;
TwoTouchModel deviceStatus = TwoTouchModel(
firstSwitch: false,
secondSwitch: false,
firstCountDown: 0,
secondCountDown: 0,
light_mode: lightStatus.off,
relay: status.off,
relay_status_1: status.off,
relay_status_2: status.off,
);
Timer? _timer;
bool twoTouchGroup = false;
List<DeviceModel> devicesList = [];
List<GroupTwoTouchModel> groupTwoTouchList = [];
bool allSwitchesOn = true;
bool toggleSchedule = true;
List<String> selectedDays = [];
bool createSchedule = false;
List<ScheduleModel> listSchedule = [];
TwoTouchBloc({required this.twoTouchId, required this.switchCode}) : super(InitialState()) {
on<InitialEvent>(_fetchTwoTouchStatus);
on<TwoTouchUpdated>(_twoTouchUpdated);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
on<ChangeSecondSwitchStatusEvent>(_changeSecondSwitch);
on<AllOffEvent>(_allOff);
on<AllOnEvent>(_allOn);
on<ChangeSlidingSegment>(_changeSliding);
on<SetCounterValue>(_setCounterValue);
on<GetCounterEvent>(_getCounterValue);
on<TickTimer>(_onTickTimer);
on<OnClose>(_onClose);
on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff);
on<ToggleDaySelectionEvent>(toggleDaySelection);
on<TwoTouchSave>(saveSchedule);
on<GetScheduleEvent>(getSchedule);
on<ToggleScheduleEvent>(toggleRepeat);
on<DeleteScheduleEvent>(deleteSchedule);
on<ToggleSelectedEvent>(toggleSelectedIndex);
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
on<InitialWizardEvent>(_fetchTwoTouchWizardStatus);
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<ChangeSecondWizardSwitchStatusEvent>(_changeSecondWizardSwitch);
on<ChangeStatusEvent>(_changeStatus);
}
DateTime? selectedTime = DateTime.now();
int selectedTabIndex = 0;
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<TwoTouchState> emit) {
emit(LoadingInitialState());
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<TwoTouchState> emit) {
emit(LoadingInitialState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
void _fetchTwoTouchStatus(InitialEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(twoTouchId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = TwoTouchModel.fromJson(statusModelList);
emit(UpdateState(twoTouchModel: deviceStatus));
// _listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
_listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoTouchId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = TwoTouchModel.fromJson(statusList);
if (!isClosed) {
add(TwoTouchUpdated());
}
});
} catch (_) {}
}
_twoTouchUpdated(TwoTouchUpdated event, Emitter<TwoTouchState> emit) {
emit(UpdateState(twoTouchModel: deviceStatus));
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
deviceStatus.firstSwitch = !event.value;
emit(UpdateState(twoTouchModel: deviceStatus));
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: twoTouchId, code: 'switch_1', value: !event.value),
twoTouchId);
if (!response['success']) {
add(const InitialEvent());
}
});
} catch (_) {
add(const InitialEvent());
}
}
void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
deviceStatus.secondSwitch = !event.value;
emit(UpdateState(twoTouchModel: deviceStatus));
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 100), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: twoTouchId, code: 'switch_2', value: !event.value),
twoTouchId);
if (!response['success']) {
add(const InitialEvent());
}
});
} catch (_) {
add(const InitialEvent());
}
}
void _allOff(AllOffEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
deviceStatus.firstSwitch = false;
deviceStatus.secondSwitch = false;
emit(UpdateState(twoTouchModel: deviceStatus));
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
twoTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
twoTouchId),
]);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent());
}
}
void _allOn(AllOnEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
deviceStatus.firstSwitch = true;
deviceStatus.secondSwitch = true;
emit(UpdateState(twoTouchModel: deviceStatus));
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
twoTouchId),
DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: twoTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
twoTouchId),
]);
if (response.every((element) => !element['success'])) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(const InitialEvent());
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
for (int i = 0; i < groupTwoTouchList.length; i++) {
groupTwoTouchList[i].firstSwitch = true;
groupTwoTouchList[i].secondSwitch = true;
}
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: true));
List<String> allDeviceIds = groupTwoTouchList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: true,
);
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: true,
);
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
for (int i = 0; i < groupTwoTouchList.length; i++) {
groupTwoTouchList[i].firstSwitch = false;
groupTwoTouchList[i].secondSwitch = false;
}
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: false));
List<String> allDeviceIds = groupTwoTouchList.map((device) => device.deviceId).toList();
final response1 = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: false,
);
final response2 = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: allDeviceIds,
value: false,
);
if (response1['failedResults'].toString() != '[]' ||
response2['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
}
void _changeSliding(ChangeSlidingSegment event, Emitter<TwoTouchState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value));
}
void _setCounterValue(SetCounterValue event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
int seconds = 0;
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: twoTouchId, code: event.deviceCode, value: seconds),
twoTouchId);
if (response['success'] ?? false) {
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown = seconds;
} else if (event.deviceCode == 'countdown_2') {
deviceStatus.secondCountDown = seconds;
}
} else {
emit(const FailedState(error: 'Something went wrong'));
return;
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
if (seconds > 0) {
_onStartTimer(seconds);
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
void _getCounterValue(GetCounterEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingInitialState());
try {
add(GetScheduleEvent());
var response = await DevicesAPI.getDeviceStatus(twoTouchId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = TwoTouchModel.fromJson(statusModelList);
if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown > 0
? _onStartTimer(deviceStatus.firstCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
} else if (event.deviceCode == 'countdown_2') {
deviceStatus.secondCountDown > 0
? _onStartTimer(deviceStatus.secondCountDown)
: emit(UpdateTimerState(seconds: deviceStatus.secondCountDown));
}
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _onClose(OnClose event, Emitter<TwoTouchState> emit) {
_timer?.cancel();
}
void _onStartTimer(int seconds) {
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
add(TickTimer(seconds - timer.tick));
});
}
void _onTickTimer(TickTimer event, Emitter<TwoTouchState> emit) {
if (event.remainingTime > 0) {
emit(TimerRunInProgress(event.remainingTime));
} else {
_timer?.cancel();
emit(TimerRunComplete());
}
}
List<Map<String, String>> days = [
{"day": "Sun", "key": "Sun"},
{"day": "Mon", "key": "Mon"},
{"day": "Tue", "key": "Tue"},
{"day": "Wed", "key": "Wed"},
{"day": "Thu", "key": "Thu"},
{"day": "Fri", "key": "Fri"},
{"day": "Sat", "key": "Sat"},
];
Future<void> toggleDaySelection(
ToggleDaySelectionEvent event,
Emitter<TwoTouchState> emit,
) async {
emit(LoadingInitialState());
if (selectedDays.contains(event.key)) {
selectedDays.remove(event.key);
} else {
selectedDays.add(event.key);
}
emit(ChangeTimeState());
add(const ChangeSlidingSegment(value: 1));
}
Future<void> saveSchedule(
TwoTouchSave event,
Emitter<TwoTouchState> emit,
) async {
try {
if (selectedDays.isNotEmpty) {
emit(LoadingInitialState());
await DevicesAPI.postSchedule(
category: switchCode,
deviceId: twoTouchId,
time: getTimeStampWithoutSeconds(selectedTime).toString(),
code: switchCode,
value: toggleSchedule,
days: selectedDays);
CustomSnackBar.displaySnackBar('Save Successfully');
add(GetScheduleEvent());
emit(TwoTouchSaveSchedule());
add(const ToggleCreateScheduleEvent(index: 1));
// toggleCreateSchedule();
} else {
CustomSnackBar.displaySnackBar('Please select days');
}
} catch (e) {
emit(FailedState(error: e.toString()));
}
}
Future<void> getSchedule(
GetScheduleEvent event,
Emitter<TwoTouchState> emit,
) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.getSchedule(
category: switchCode,
deviceId: twoTouchId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
emit(InitialState());
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleRepeat(ToggleScheduleEvent event, Emitter<TwoTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule(
scheduleId: event.id, deviceUuid: twoTouchId, enable: event.toggle);
if (response == true) {
add(GetScheduleEvent());
toggleSchedule = event.toggle;
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
add(const ChangeSlidingSegment(value: 1));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
Future deleteSchedule(DeleteScheduleEvent event, Emitter<TwoTouchState> emit) async {
try {
emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id,
deviceUuid: twoTouchId,
);
if (response == true) {
add(GetScheduleEvent());
return toggleSchedule;
}
emit(IsToggleState(onOff: toggleSchedule));
add(const ChangeSlidingSegment(value: 1));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
void _fetchTwoTouchWizardStatus(InitialWizardEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingInitialState());
try {
devicesList = [];
groupTwoTouchList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', '2GT');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = TwoTouchModel.fromJson(statusModelList);
groupTwoTouchList.add(GroupTwoTouchModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
secondSwitch: deviceStatus.secondSwitch,
));
}
if (groupTwoTouchList.isNotEmpty) {
groupTwoTouchList.firstWhere((element) {
if (!element.firstSwitch || !element.secondSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesOn));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
bool allSwitchesValue = true;
groupTwoTouchList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: [event.deviceId],
value: !event.value,
);
if (response['failedResults'].toString() != '[]') {
add(InitialWizardEvent());
}
} catch (_) {
add(InitialWizardEvent());
}
}
void _changeSecondWizardSwitch(
ChangeSecondWizardSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
emit(LoadingNewSate(twoTouchModel: deviceStatus));
try {
bool allSwitchesValue = true;
groupTwoTouchList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.secondSwitch = !event.value;
}
if (!element.firstSwitch || !element.secondSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_2',
devicesUuid: [event.deviceId],
value: !event.value,
);
if (response['failedResults'].toString() != '[]') {
add(InitialWizardEvent());
}
} catch (_) {
add(InitialWizardEvent());
}
}
String statusSelected = '';
String optionSelected = '';
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<TwoTouchState> emit) async {
try {
emit(LoadingInitialState());
final Map<String, Map<String, String>> controlMap = {
"relay_status": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
"light_mode": {
'Off': 'none',
'On/Off Status': 'relay',
'Switch Position': 'pos',
},
"relay_status_1": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
"relay_status_2": {
'Power On': 'power_on',
'Power Off': 'power_off',
'Restart Memory': 'last',
},
};
final selectedControl = controlMap[optionSelected]?[statusSelected];
if (selectedControl != null) {
await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: twoTouchId, code: optionSelected, value: selectedControl),
twoTouchId,
);
} else {
emit(const FailedState(error: 'Invalid statusSelected or optionSelected'));
}
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(FailedState(error: errorMessage.toString()));
}
}
}

View File

@ -0,0 +1,162 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
abstract class TwoTouchEvent extends Equatable {
const TwoTouchEvent();
@override
List<Object> get props => [];
}
class LoadingEvent extends TwoTouchEvent {}
class TwoTouchUpdated extends TwoTouchEvent {}
class TwoTouchSave extends TwoTouchEvent {}
class ToggleScheduleEvent extends TwoTouchEvent {
final String id;
final bool toggle;
const ToggleScheduleEvent({required this.toggle, required this.id});
@override
List<Object> get props => [toggle, id];
}
class errorMessage extends TwoTouchEvent {}
class ToggleDaySelectionEvent extends TwoTouchEvent {
final String key;
const ToggleDaySelectionEvent({required this.key});
@override
List<Object> get props => [key];
}
class InitialEvent extends TwoTouchEvent {
const InitialEvent();
@override
List<Object> get props => [];
}
class ChangeFirstSwitchStatusEvent extends TwoTouchEvent {
final bool value;
final String deviceId;
const ChangeFirstSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeSecondSwitchStatusEvent extends TwoTouchEvent {
final bool value;
final String deviceId;
const ChangeSecondSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class AllOffEvent extends TwoTouchEvent {}
class AllOnEvent extends TwoTouchEvent {}
class GroupAllOnEvent extends TwoTouchEvent {}
class GroupAllOffEvent extends TwoTouchEvent {}
class ChangeSlidingSegment extends TwoTouchEvent {
final int value;
const ChangeSlidingSegment({required this.value});
@override
List<Object> get props => [value];
}
class GetCounterEvent extends TwoTouchEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class SetCounterValue extends TwoTouchEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends TwoTouchEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends TwoTouchEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends TwoTouchEvent {}
class OnClose extends TwoTouchEvent {}
class GetScheduleEvent extends TwoTouchEvent {}
class DeleteScheduleEvent extends TwoTouchEvent {
final String id;
const DeleteScheduleEvent({required this.id});
@override
List<Object> get props => [id];
}
class TabChangedEvent extends TwoTouchEvent {
final int index;
TabChangedEvent({required this.index});
}
class ToggleSelectedEvent extends TwoTouchEvent {
final int index;
const ToggleSelectedEvent({required this.index});
@override
List<Object> get props => [index];
}
class ToggleCreateScheduleEvent extends TwoTouchEvent {
final int index;
const ToggleCreateScheduleEvent({required this.index});
@override
List<Object> get props => [index];
}
class InitialWizardEvent extends TwoTouchEvent {}
class ChangeFirstWizardSwitchStatusEvent extends TwoTouchEvent {
final bool value;
final String deviceId;
const ChangeFirstWizardSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeSecondWizardSwitchStatusEvent extends TwoTouchEvent {
final bool value;
final String deviceId;
const ChangeSecondWizardSwitchStatusEvent(
{required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class ChangeStatusEvent extends TwoTouchEvent {
final String deviceId;
final BuildContext context;
const ChangeStatusEvent({this.deviceId = '',required this.context});
}

View File

@ -0,0 +1,91 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/group_two_touch_model.dart';
import 'package:syncrow_app/features/devices/model/two_touch_model.dart';
class TwoTouchState extends Equatable {
const TwoTouchState();
@override
List<Object> get props => [];
}
class InitialState extends TwoTouchState {}
class TwoTouchSaveSchedule extends TwoTouchState {}
class ChangeTimeState extends TwoTouchState {}
class LoadingInitialState extends TwoTouchState {}
class UpdateState extends TwoTouchState {
final TwoTouchModel twoTouchModel;
const UpdateState({required this.twoTouchModel});
@override
List<Object> get props => [TwoTouchModel];
}
class LoadingNewSate extends TwoTouchState {
final TwoTouchModel twoTouchModel;
const LoadingNewSate({required this.twoTouchModel});
@override
List<Object> get props => [TwoTouchModel];
}
class UpdateGroupState extends TwoTouchState {
final List<GroupTwoTouchModel> twoTouchList;
final bool allSwitches;
const UpdateGroupState({required this.twoTouchList, required this.allSwitches});
@override
List<Object> get props => [twoTouchList, allSwitches];
}
class FailedState extends TwoTouchState {
final String error;
const FailedState({required this.error});
@override
List<Object> get props => [error];
}
class ChangeSlidingSegmentState extends TwoTouchState {
final int value;
const ChangeSlidingSegmentState({required this.value});
@override
List<Object> get props => [value];
}
class UpdateTimerState extends TwoTouchState {
final int seconds;
const UpdateTimerState({required this.seconds});
@override
List<Object> get props => [seconds];
}
class TimerRunInProgress extends TwoTouchState {
final int remainingTime;
const TimerRunInProgress(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class TimerRunComplete extends TwoTouchState {}
class IsToggleState extends TwoTouchState {
final bool? onOff;
const IsToggleState({this.onOff});
}
class UpdateCreateScheduleState extends TwoTouchState {
final bool createSchedule;
UpdateCreateScheduleState(this.createSchedule);
}

View File

@ -30,7 +30,7 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
}
deviceStatus = WallSensorModel.fromJson(statusModelList);
emit(UpdateState(wallSensorModel: deviceStatus));
_listenToChanges();
// _listenToChanges();
} catch (e) {
emit(FailedState(error: e.toString()));
return;

View File

@ -1,9 +1,12 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.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/devices/bloc/water_heater_bloc/water_heater_event.dart';
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_state.dart';
import 'package:syncrow_app/features/devices/model/GroupWHModel.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/schedule_model.dart';
@ -16,9 +19,7 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
final String whId;
final String switchCode;
WHModel deviceStatus = WHModel(
firstSwitch: false,firstCountDown: 0
);
WHModel deviceStatus = WHModel(firstSwitch: false, firstCountDown: 0);
List<WHModel> deviceStatusList = [];
List<DeviceModel> devicesList = [];
bool allAcsPage = false;
@ -27,15 +28,14 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
int globalTemp = 25;
Timer? _timer;
bool toggleSchedule = true;
List<String> selectedDays = [];
bool createSchedule = false;
bool createCirculate = false;
List<ScheduleModel> listSchedule = [];
DateTime? selectedTime=DateTime.now();
DateTime? selectedTime = DateTime.now();
WaterHeaterBloc({required this.whId,required this.switchCode}) : super(WHInitialState()) {
WaterHeaterBloc({required this.whId, required this.switchCode}) : super(WHInitialState()) {
on<WaterHeaterInitial>(_fetchWaterHeaterStatus);
on<WaterHeaterSwitch>(_changeFirstSwitch);
on<SetCounterValue>(_setCounterValue);
@ -49,8 +49,15 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
on<OnClose>(_onClose);
on<SelectTimeEvent>(showTime);
on<ToggleSelectedEvent>(toggleSelectedIndex);
on<ToggleSelectedEvent>(toggleSelectedIndex);
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
on<InitialWizardEvent>(_fetchWHWizardStatus);
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff);
on<ToggleCreateCirculate>(_toggleCreateCirculate);
on<WaterHeaterUpdated>(_waterHeaterUpdated);
}
void _fetchWaterHeaterStatus(WaterHeaterInitial event, Emitter<WaterHeaterState> emit) async {
@ -61,9 +68,10 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = WHModel.fromJson(statusModelList, );
deviceStatus = WHModel.fromJson(
statusModelList,
);
emit(UpdateState(whModel: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
} catch (e) {
emit(WHFailedState(errorMessage: e.toString()));
@ -71,6 +79,34 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
_listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$whId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: element['value']));
});
deviceStatus = WHModel.fromJson(statusList);
if (!isClosed) {
add(WaterHeaterUpdated());
}
});
} catch (_) {}
}
_waterHeaterUpdated(WaterHeaterUpdated event, Emitter<WaterHeaterState> emit) async {
emit(WHLoadingState());
emit(UpdateState(whModel: deviceStatus));
}
void _changeFirstSwitch(WaterHeaterSwitch event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
@ -82,14 +118,11 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
_timer = Timer(const Duration(milliseconds: 500), () async {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: whId,
code: 'switch_1',
value: deviceStatus.firstSwitch ),
DeviceControlModel(deviceId: whId, code: 'switch_1', value: deviceStatus.firstSwitch),
whId);
if (!response['success']) {
// add(InitialEvent(groupScreen: oneGangGroup));
// add(InitialEvent(groupScreen: oneGangGroup));
}
});
} catch (_) {
@ -97,10 +130,6 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
//=====================---------- timer ----------------------------------------
void _setCounterValue(SetCounterValue event, Emitter<WaterHeaterState> emit) async {
@ -109,8 +138,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
try {
seconds = event.duration.inSeconds;
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: whId, code: event.deviceCode, value: seconds),
whId);
DeviceControlModel(deviceId: whId, code: event.deviceCode, value: seconds), whId);
if (response['success'] ?? false) {
if (event.deviceCode == 'countdown_1') {
@ -148,7 +176,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
}
} catch (e) {
WHFailedState(errorMessage: e.toString());
WHFailedState(errorMessage: e.toString());
return;
}
}
@ -173,13 +201,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
//=====================---------- Schedule ----------------------------------------
List<Map<String, String>> days = [
{"day": "Sun", "key": "Sun"},
{"day": "Mon", "key": "Mon"},
@ -190,11 +213,14 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
{"day": "Sat", "key": "Sat"},
];
Future<void> saveSchedule(ScheduleSave event, Emitter<WaterHeaterState> emit,) async {
Future<void> saveSchedule(
ScheduleSave event,
Emitter<WaterHeaterState> emit,
) async {
try {
if(selectedDays.isNotEmpty) {
if (selectedDays.isNotEmpty) {
emit(WHLoadingState());
final response = await DevicesAPI.postSchedule(
await DevicesAPI.postSchedule(
category: switchCode,
deviceId: whId,
time: getTimeStampWithoutSeconds(selectedTime).toString(),
@ -204,21 +230,24 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
CustomSnackBar.displaySnackBar('Save Successfully');
add(GetScheduleEvent());
emit(SaveSchedule());
add(const ToggleCreateScheduleEvent(index:1 ));
}else{
add(const ToggleCreateScheduleEvent(index: 1));
} else {
CustomSnackBar.displaySnackBar('Please select days');
}
} catch (e) {
emit(WHFailedState(errorMessage:e.toString()));
emit(WHFailedState(errorMessage: e.toString()));
}
}
Future<void> getSchedule(GetScheduleEvent event, Emitter<WaterHeaterState> emit,) async {
Future<void> getSchedule(
GetScheduleEvent event,
Emitter<WaterHeaterState> emit,
) async {
try {
emit(WHLoadingState());
final response = await DevicesAPI.getSchedule(
category: switchCode,
deviceId: whId ,
deviceId: whId,
);
List<dynamic> jsonData = response;
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
@ -232,13 +261,12 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
dateTime.day, dateTime.hour, dateTime.minute);
DateTime dateTimeWithoutSeconds =
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
}
Future toggleChange(
ToggleScheduleEvent event, Emitter<WaterHeaterState> emit) async {
Future toggleChange(ToggleScheduleEvent event, Emitter<WaterHeaterState> emit) async {
try {
emit(WHLoadingState());
final response = await DevicesAPI.changeSchedule(
@ -252,17 +280,17 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(WHFailedState(errorMessage: errorMessage.toString()));
emit(WHFailedState(errorMessage: errorMessage.toString()));
}
}
Future deleteSchedule(
DeleteScheduleEvent event, Emitter<WaterHeaterState> emit) async {
Future deleteSchedule(DeleteScheduleEvent event, Emitter<WaterHeaterState> emit) async {
try {
emit(WHLoadingState());
final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id,
deviceUuid: whId, );
deviceUuid: whId,
);
if (response == true) {
add(GetScheduleEvent());
return toggleSchedule;
@ -275,47 +303,32 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
}
}
// void toggleCreateSchedule() {
// emit(WHLoadingState());
// createSchedule = !createSchedule;
// selectedDays.clear();
// selectedTime=DateTime.now();
// emit(UpdateCreateScheduleState(createSchedule));
// }
void toggleCreateCirculate() {
emit(WHLoadingState());
void _toggleCreateCirculate(ToggleCreateCirculate event, Emitter<WaterHeaterState> emit) {
emit(WHLoadingState());
createCirculate = !createCirculate;
selectedDays.clear();
selectedTime=DateTime.now();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createCirculate));
}
// void toggleSelectedIndex(index) {
// emit(WHLoadingState());
// selectedTabIndex = index;
// emit(ChangeSlidingSegmentState(value: selectedTabIndex));
// }
void toggleSelectedIndex( ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
emit(WHLoadingState());
selectedTabIndex =event.index;
selectedTabIndex = event.index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
emit(WHLoadingState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
emit(WHLoadingState());
createSchedule = !createSchedule;
selectedDays.clear();
selectedTime = DateTime.now();
emit(UpdateCreateScheduleState(createSchedule));
}
Future<void> toggleDaySelection(
ToggleDaySelectionEvent event,
Emitter<WaterHeaterState> emit,
) async {
ToggleDaySelectionEvent event,
Emitter<WaterHeaterState> emit,
) async {
emit(WHLoadingState());
if (selectedDays.contains(event.key)) {
selectedDays.remove(event.key);
@ -327,9 +340,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
int selectedTabIndex = 0;
showTime(SelectTimeEvent event, Emitter<WaterHeaterState> emit) async {
final TimeOfDay? timePicked = await showTimePicker(
await showTimePicker(
context: event.context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
@ -350,4 +362,127 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
},
);
}
List<GroupWHModel> groupWaterHeaterList = [];
bool allSwitchesOn = true;
void _changeFirstWizardSwitch(
ChangeFirstWizardSwitchStatusEvent event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
try {
bool allSwitchesValue = true;
groupWaterHeaterList.forEach((element) {
if (element.deviceId == event.deviceId) {
element.firstSwitch = !event.value;
}
if (!element.firstSwitch) {
allSwitchesValue = false;
}
});
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue));
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: [event.deviceId],
value: !event.value,
);
if (response['failedResults'].toString() != '[]') {
add(InitialWizardEvent());
}
} catch (_) {
add(InitialWizardEvent());
}
}
void _fetchWHWizardStatus(InitialWizardEvent event, Emitter<WaterHeaterState> emit) async {
emit(WHLoadingState());
try {
devicesList = [];
groupWaterHeaterList = [];
allSwitchesOn = true;
devicesList = await DevicesAPI.getDeviceByGroupName(
HomeCubit.getInstance().selectedSpace?.id ?? '', 'WH');
for (int i = 0; i < devicesList.length; i++) {
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = WHModel.fromJson(statusModelList);
groupWaterHeaterList.add(GroupWHModel(
deviceId: devicesList[i].uuid ?? '',
deviceName: devicesList[i].name ?? '',
firstSwitch: deviceStatus.firstSwitch,
));
}
if (groupWaterHeaterList.isNotEmpty) {
groupWaterHeaterList.firstWhere((element) {
if (!element.firstSwitch) {
allSwitchesOn = false;
}
return true;
});
}
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn));
} catch (e) {
// emit(FailedState(error: e.toString()));
return;
}
}
void _groupAllOn(GroupAllOnEvent event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
try {
for (int i = 0; i < groupWaterHeaterList.length; i++) {
groupWaterHeaterList[i].firstSwitch = true;
}
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: true));
List<String> allDeviceIds = groupWaterHeaterList.map((device) => device.deviceId).toList();
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: true,
);
if (response['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
}
void _groupAllOff(GroupAllOffEvent event, Emitter<WaterHeaterState> emit) async {
emit(LoadingNewSate(whModel: deviceStatus));
try {
for (int i = 0; i < groupWaterHeaterList.length; i++) {
groupWaterHeaterList[i].firstSwitch = false;
}
emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: false));
List<String> allDeviceIds = groupWaterHeaterList.map((device) => device.deviceId).toList();
final response = await DevicesAPI.deviceBatchController(
code: 'switch_1',
devicesUuid: allDeviceIds,
value: false,
);
if (response['failedResults'].toString() != '[]') {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(InitialWizardEvent());
}
}
}

View File

@ -28,7 +28,6 @@ class WaterHeaterInitial extends WaterHeaterEvent {
class WaterHeaterChangeStatus extends WaterHeaterEvent {}
class GetCounterEvent extends WaterHeaterEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@ -66,25 +65,27 @@ class StopTimer extends WaterHeaterEvent {}
class OnClose extends WaterHeaterEvent {}
//------------------- Schedule ----------=---------
class GetScheduleEvent extends WaterHeaterEvent {}
class ScheduleSave extends WaterHeaterEvent {}
class ToggleScheduleEvent extends WaterHeaterEvent {
final String id;
final bool toggle;
const ToggleScheduleEvent({required this.toggle,required this.id});
const ToggleScheduleEvent({required this.toggle, required this.id});
@override
List<Object> get props => [toggle,id];
List<Object> get props => [toggle, id];
}
class ToggleDaySelectionEvent extends WaterHeaterEvent {
class ToggleDaySelectionEvent extends WaterHeaterEvent {
final String key;
const ToggleDaySelectionEvent({required this.key});
@override
List<Object> get props => [key];
}
class DeleteScheduleEvent extends WaterHeaterEvent {
final String id;
const DeleteScheduleEvent({required this.id});
@ -100,7 +101,6 @@ class SelectTimeEvent extends WaterHeaterEvent {
List<Object> get props => [context, isEffective];
}
class ToggleSelectedEvent extends WaterHeaterEvent {
final int index;
const ToggleSelectedEvent({required this.index});
@ -108,7 +108,6 @@ class ToggleSelectedEvent extends WaterHeaterEvent {
List<Object> get props => [index];
}
class ToggleCreateScheduleEvent extends WaterHeaterEvent {
final int index;
const ToggleCreateScheduleEvent({required this.index});
@ -116,10 +115,25 @@ class ToggleCreateScheduleEvent extends WaterHeaterEvent {
List<Object> get props => [index];
}
class ToggleCreateCirculateEvent extends WaterHeaterEvent {
class ToggleCreateCirculateEvent extends WaterHeaterEvent {
final int index;
const ToggleCreateCirculateEvent({required this.index});
@override
List<Object> get props => [index];
}
class InitialWizardEvent extends WaterHeaterEvent {}
class ChangeFirstWizardSwitchStatusEvent extends WaterHeaterEvent {
final bool value;
final String deviceId;
const ChangeFirstWizardSwitchStatusEvent({required this.value, this.deviceId = ''});
@override
List<Object> get props => [value, deviceId];
}
class GroupAllOnEvent extends WaterHeaterEvent {}
class GroupAllOffEvent extends WaterHeaterEvent {}
class ToggleCreateCirculate extends WaterHeaterEvent {}

View File

@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/GroupWHModel.dart';
import 'package:syncrow_app/features/devices/model/water_heater.dart';
abstract class WaterHeaterState extends Equatable {
@ -13,13 +14,8 @@ class WHInitialState extends WaterHeaterState {}
class WHLoadingState extends WaterHeaterState {}
class WHChangeLoading extends WaterHeaterState {
// final WHStatusModel WHStatusModel;
const WHChangeLoading(
// {required this. WHStatusModel}
);
// @override
// List<Object> get props => [acStatusModel];
}
class WHModifyingState extends WaterHeaterState {
@ -110,4 +106,17 @@ class ChangeSlidingSegmentState extends WaterHeaterState {
@override
List<Object> get props => [value];
}
}
class UpdateGroupState extends WaterHeaterState {
final List<GroupWHModel> twoGangList;
final bool allSwitches;
const UpdateGroupState({required this.twoGangList, required this.allSwitches});
@override
List<Object> get props => [twoGangList, allSwitches];
}

View File

@ -0,0 +1,165 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/water_leak_bloc/water_leak_event.dart';
import 'package:syncrow_app/features/devices/bloc/water_leak_bloc/water_leak_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/water_leak_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class WaterLeakBloc extends Bloc<WaterLeakEvent, WaterLeakState> {
final String WLId;
WaterLeakBloc({
required this.WLId,
}) : super(const WaterLeakState()) {
on<WaterLeakInitial>(_fetchStatus);
on<ReportLogsInitial>(fetchLogsForLastMonth);
on<ToggleLowBatteryEvent>(_toggleLowBattery);
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
on<ToggleWaterLeakAlarmEvent>(_toggleWaterLeakAlarm);
}
Timer? _timer;
bool lowBattery = false;
bool closingReminder = false;
bool waterAlarm = false;
WaterLeakModel deviceStatus =
WaterLeakModel(waterContactState: 'normal', batteryPercentage: 0);
void _fetchStatus(
WaterLeakInitial event, Emitter<WaterLeakState> emit) async {
emit(WaterLeakLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(WLId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = WaterLeakModel.fromJson(
statusModelList,
);
emit(UpdateState(waterSensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
} catch (e) {
emit(WaterLeakFailedState(errorMessage: e.toString()));
return;
}
}
void _toggleLowBattery(
ToggleLowBatteryEvent event, Emitter<WaterLeakState> emit) async {
emit(LoadingNewSate(waterSensor: deviceStatus));
try {
lowBattery = event.isLowBatteryEnabled;
emit(UpdateState(waterSensor: deviceStatus));
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: WLId,
code: 'low_battery',
value: lowBattery,
),
WLId,
);
} catch (e) {
emit(WaterLeakFailedState(errorMessage: e.toString()));
}
}
void _toggleClosingReminder(
ToggleClosingReminderEvent event, Emitter<WaterLeakState> emit) async {
emit(LoadingNewSate(waterSensor: deviceStatus));
try {
closingReminder = event.isClosingReminderEnabled;
emit(UpdateState(waterSensor: deviceStatus));
// API call to update the state, if necessary
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: WLId,
code: 'closing_reminder',
value: closingReminder,
),
WLId,
);
} catch (e) {
emit(WaterLeakFailedState(errorMessage: e.toString()));
}
}
void _toggleWaterLeakAlarm(
ToggleWaterLeakAlarmEvent event, Emitter<WaterLeakState> emit) async {
emit(LoadingNewSate(waterSensor: deviceStatus));
try {
waterAlarm = event.isWaterLeakAlarmEnabled;
emit(UpdateState(waterSensor: deviceStatus));
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: WLId,
code: 'water_alarm',
value: waterAlarm,
),
WLId,
);
} catch (e) {
emit(WaterLeakFailedState(errorMessage: e.toString()));
}
}
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<WaterLeakState> emit) async {
DateTime now = DateTime.now();
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
int startTime = lastMonth.millisecondsSinceEpoch;
int endTime = now.millisecondsSinceEpoch;
try {
emit(WaterLeakLoadingState());
var response = await DevicesAPI.getReportLogs(
startTime: startTime.toString(),
endTime: endTime.toString(),
deviceUuid: WLId,
code: 'watersensor_state',
);
recordGroups = response;
emit(UpdateState(waterSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
emit(WaterLeakFailedState(errorMessage: errorMessage));
}
}
_listenToChanges() {
try {
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$WLId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {
statusList.add(StatusModel(code: element['code'], value: true));
});
deviceStatus = WaterLeakModel.fromJson(statusList);
if (!isClosed) {
add(
WaterLeakSwitch(switchD: deviceStatus.waterContactState),
);
}
});
} catch (_) {}
}
}

View File

@ -0,0 +1,102 @@
import 'package:equatable/equatable.dart';
abstract class WaterLeakEvent extends Equatable {
const WaterLeakEvent();
@override
List<Object> get props => [];
}
class WaterLeakLoading extends WaterLeakEvent {}
class WaterLeakSwitch extends WaterLeakEvent {
final String switchD;
final String deviceId;
final String productId;
const WaterLeakSwitch({required this.switchD, this.deviceId = '', this.productId = ''});
@override
List<Object> get props => [switchD, deviceId, productId];
}
class WaterLeakUpdated extends WaterLeakEvent {}
class WaterLeakInitial extends WaterLeakEvent {
const WaterLeakInitial();
}
class ReportLogsInitial extends WaterLeakEvent {
const ReportLogsInitial();
}
class WaterLeakChangeStatus extends WaterLeakEvent {}
class GetCounterEvent extends WaterLeakEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class ToggleLowBatteryEvent extends WaterLeakEvent {
final bool isLowBatteryEnabled;
const ToggleLowBatteryEvent(this.isLowBatteryEnabled);
@override
List<Object> get props => [isLowBatteryEnabled];
}
class ToggleClosingReminderEvent extends WaterLeakEvent {
final bool isClosingReminderEnabled;
const ToggleClosingReminderEvent(this.isClosingReminderEnabled);
@override
List<Object> get props => [isClosingReminderEnabled];
}
class ToggleWaterLeakAlarmEvent extends WaterLeakEvent {
final bool isWaterLeakAlarmEnabled;
const ToggleWaterLeakAlarmEvent(this.isWaterLeakAlarmEnabled);
@override
List<Object> get props => [isWaterLeakAlarmEnabled];
}
class SetCounterValue extends WaterLeakEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends WaterLeakEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends WaterLeakEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends WaterLeakEvent {}
class OnClose extends WaterLeakEvent {}

View File

@ -0,0 +1,39 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/water_leak_model.dart';
class WaterLeakState extends Equatable {
const WaterLeakState();
@override
List<Object> get props => [];
}
class WaterLeakInitialState extends WaterLeakState {}
class WaterLeakLoadingState extends WaterLeakState {}
class WaterLeakFailedState extends WaterLeakState {
final String errorMessage;
const WaterLeakFailedState({required this.errorMessage});
@override
List<Object> get props => [errorMessage];
}
class UpdateState extends WaterLeakState {
final WaterLeakModel waterSensor;
const UpdateState({required this.waterSensor});
@override
List<Object> get props => [waterSensor];
}
class LoadingNewSate extends WaterLeakState {
final WaterLeakModel waterSensor;
const LoadingNewSate({required this.waterSensor});
@override
List<Object> get props => [waterSensor];
}

View File

@ -0,0 +1,11 @@
class GroupWHModel {
final String deviceId;
final String deviceName;
bool firstSwitch;
GroupWHModel({
required this.deviceId,
required this.deviceName,
required this.firstSwitch,
});
}

View File

@ -0,0 +1,29 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class CurtainModel {
String control;
int percent;
CurtainModel({
required this.control,
required this.percent,
});
factory CurtainModel.fromJson(List<StatusModel> jsonList) {
late String _control;
late int _percent;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'control') {
_control = jsonList[i].value ?? false;
}
if (jsonList[i].code == 'percent_control') {
_percent = jsonList[i].value ?? 0;
}
}
//percent_control
return CurtainModel(
control: _control,
percent: _percent,
);
}
}

View File

@ -67,4 +67,8 @@ Map<DeviceType, String> deviceTypeIconMap = {
DeviceType.WH: Assets.waterHeaterIcon,
DeviceType.DS: Assets.doorSensorIcon,
DeviceType.Other: Assets.assetsIconsAC,
DeviceType.OneTouch: Assets.gang1touch,
DeviceType.TowTouch: Assets.gang2touch,
DeviceType.ThreeTouch: Assets.gang3touch,
DeviceType.GarageDoor: Assets.garageIcon
};

View File

@ -66,6 +66,18 @@ class DeviceModel {
tempIcon = Assets.waterHeaterIcon;
} else if (type == DeviceType.DS) {
tempIcon = Assets.doorSensorIcon;
} else if (type == DeviceType.OneTouch) {
tempIcon = Assets.gang1touch;
} else if (type == DeviceType.TowTouch) {
tempIcon = Assets.gang2touch;
} else if (type == DeviceType.GarageDoor) {
tempIcon = Assets.garageIcon;
} else if (type == DeviceType.ThreeTouch) {
tempIcon = Assets.gang3touch;
} else if (type == DeviceType.WaterLeak) {
tempIcon = Assets.waterLeakIcon;
} else if (type == DeviceType.PC) {
tempIcon = Assets.powerClampIcon;
} else {
tempIcon = Assets.assetsIconsLogo;
}

View File

@ -27,6 +27,33 @@ class DeviceReport {
};
}
class EventDevice {
final String? code;
final DateTime? eventTime;
final String? value;
EventDevice({
this.code,
this.eventTime,
this.value,
});
EventDevice.fromJson(Map<String, dynamic> json)
: code = json['code'] as String?,
eventTime = json['eventTime'] ,
value = json['value'] as String?;
Map<String, dynamic> toJson() => {
'code': code,
'eventTime': eventTime,
'value': value,
};
}
class DeviceEvent {
final String? code;
final int? eventTime;

View File

@ -0,0 +1,81 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class GarageDoorModel {
bool switch1;
bool doorContactState;
int countdown1;
int countdownAlarm;
String doorControl1;
bool voiceControl1;
String doorState1;
int batteryPercentage;
int tr_timecon;
GarageDoorModel({
required this.switch1,
required this.doorContactState,
required this.countdown1,
required this.countdownAlarm,
required this.doorControl1,
required this.voiceControl1,
required this.doorState1,
required this.batteryPercentage,
required this.tr_timecon,
});
factory GarageDoorModel.fromJson(List<StatusModel> jsonList) {
late bool _switch1 = false;
late bool _doorContactState = false;
late int _countdown1 = 0;
late int _countdownAlarm = 0;
late String _doorControl1 = "closed";
late bool _voiceControl1 = false;
late String _doorState1 = "closed";
late int _batteryPercentage = 0;
late int _tr_timecon = 0;
for (var status in jsonList) {
switch (status.code) {
case 'tr_timecon':
_tr_timecon = status.value ?? "closed";
break;
case 'switch_1':
_switch1 = status.value ?? false;
break;
case 'doorcontact_state':
_doorContactState = status.value ?? false;
break;
case 'countdown_1':
_countdown1 = status.value ?? 0;
break;
case 'countdown_alarm':
_countdownAlarm = status.value ?? 0;
break;
case 'door_control_1':
_doorControl1 = status.value ?? "closed";
break;
case 'voice_control_1':
_voiceControl1 = status.value ?? false;
break;
case 'door_state_1':
_doorState1 = status.value ?? "closed";
break;
case 'battery_percentage':
_batteryPercentage = status.value ?? 0;
break;
}
}
return GarageDoorModel(
switch1: _switch1,
doorContactState: _doorContactState,
countdown1: _countdown1,
countdownAlarm: _countdownAlarm,
doorControl1: _doorControl1,
voiceControl1: _voiceControl1,
doorState1: _doorState1,
batteryPercentage: _batteryPercentage,
tr_timecon: _tr_timecon);
}
}

View File

@ -0,0 +1,13 @@
class GroupCurtainModel {
final String deviceId;
final String deviceName;
String firstSwitch;
int percentControl;
GroupCurtainModel({
required this.deviceId,
required this.deviceName,
required this.firstSwitch,
required this.percentControl,
});
}

View File

@ -0,0 +1,11 @@
class GroupGarageModel {
final String deviceId;
final String deviceName;
bool firstSwitch;
GroupGarageModel({
required this.deviceId,
required this.deviceName,
required this.firstSwitch,
});
}

View File

@ -0,0 +1,11 @@
class GroupOneTouchModel {
final String deviceId;
final String deviceName;
bool firstSwitch;
GroupOneTouchModel({
required this.deviceId,
required this.deviceName,
required this.firstSwitch,
});
}

View File

@ -0,0 +1,15 @@
class GroupThreeTouchModel {
final String deviceId;
final String deviceName;
bool firstSwitch;
bool secondSwitch;
bool thirdSwitch;
GroupThreeTouchModel({
required this.deviceId,
required this.deviceName,
required this.firstSwitch,
required this.secondSwitch,
required this.thirdSwitch,
});
}

View File

@ -0,0 +1,13 @@
class GroupTwoTouchModel {
final String deviceId;
final String deviceName;
bool firstSwitch;
bool secondSwitch;
GroupTwoTouchModel({
required this.deviceId,
required this.deviceName,
required this.firstSwitch,
required this.secondSwitch,
});
}

View File

@ -0,0 +1,50 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class OneTouchModel {
bool firstSwitch;
int firstCountDown;
status relay;
lightStatus light_mode;
status relay_status_1;
OneTouchModel(
{required this.firstSwitch,
required this.firstCountDown,
required this.light_mode,
required this.relay,
required this.relay_status_1
});
factory OneTouchModel.fromJson(List<StatusModel> jsonList) {
late bool _switch;
late int _count;
late String _relay;
late String _light_mode;
late String relay_status_1;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'switch_1') {
_switch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'countdown_1') {
_count = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status') {
_relay = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'light_mode') {
_light_mode = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status_1') {
relay_status_1 = jsonList[i].value ?? 0;
}
}
return OneTouchModel(
firstSwitch: _switch,
firstCountDown: _count,
light_mode: lightStatusExtension.fromString(_light_mode) ,
relay: StatusExtension.fromString(_relay ) ,
relay_status_1: StatusExtension.fromString(relay_status_1 )
);
}
}

View File

@ -0,0 +1,86 @@
// PowerClampModel class to represent the response
class PowerClampModel {
String productUuid;
String productType;
PowerStatus status;
PowerClampModel({
required this.productUuid,
required this.productType,
required this.status,
});
factory PowerClampModel.fromJson(Map<String, dynamic> json) {
return PowerClampModel(
productUuid: json['productUuid'],
productType: json['productType'],
status: PowerStatus.fromJson(json['status']),
);
}
}
class PowerStatus {
Phase phaseA;
Phase phaseB;
Phase phaseC;
Phase general;
PowerStatus({
required this.phaseA,
required this.phaseB,
required this.phaseC,
required this.general,
});
factory PowerStatus.fromJson(Map<String, dynamic> json) {
return PowerStatus(
phaseA: Phase.fromJson(json['phaseA']),
phaseB: Phase.fromJson(json['phaseB']),
phaseC: Phase.fromJson(json['phaseC']),
general: Phase.fromJson(json['general']
// List<DataPoint>.from(
// json['general'].map((x) => DataPoint.fromJson(x))),
));
}
}
class Phase {
List<DataPoint> dataPoints;
Phase({required this.dataPoints});
factory Phase.fromJson(List<dynamic> json) {
return Phase(
dataPoints: json.map((x) => DataPoint.fromJson(x)).toList(),
);
}
}
class DataPoint {
dynamic code;
dynamic customName;
dynamic dpId;
dynamic time;
dynamic type;
dynamic value;
DataPoint({
required this.code,
required this.customName,
required this.dpId,
required this.time,
required this.type,
required this.value,
});
factory DataPoint.fromJson(Map<String, dynamic> json) {
return DataPoint(
code: json['code'],
customName: json['customName'],
dpId: json['dpId'],
time: json['time'],
type: json['type'],
value: json['value'],
);
}
}

View File

@ -0,0 +1,35 @@
import 'package:syncrow_app/features/devices/model/device_model.dart';
class SubSpaceModel {
final String? id;
final String? name;
List<DeviceModel>? devices;
SubSpaceModel({
required this.id,
required this.name,
required this.devices,
});
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'devices': devices?.map((device) => device.toJson()).toList(),
};
}
factory SubSpaceModel.fromJson(Map<String, dynamic> json) {
List<DeviceModel> devices = [];
if (json['devices'] != null) {
for (var device in json['devices']) {
devices.add(DeviceModel.fromJson(device));
}
}
return SubSpaceModel(
id: json['uuid'],
name: json['subspaceName'],
devices: devices,
);
}
}

View File

@ -0,0 +1,81 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class ThreeTouchModel {
bool firstSwitch;
bool secondSwitch;
bool thirdSwitch;
int firstCountDown;
int secondCountDown;
int thirdCountDown;
status relay;
lightStatus light_mode;
status relay_status_1;
status relay_status_2;
status relay_status_3;
ThreeTouchModel(
{required this.firstSwitch,
required this.secondSwitch,
required this.thirdSwitch,
required this.firstCountDown,
required this.secondCountDown,
required this.thirdCountDown,
required this.light_mode,
required this.relay,
required this.relay_status_1,
required this.relay_status_2,
required this.relay_status_3});
factory ThreeTouchModel.fromJson(List<StatusModel> jsonList) {
late bool _firstSwitch;
late bool _secondSwitch;
late bool _thirdSwitch;
late int _firstCount;
late int _secondCount;
late int _thirdCount;
late String _relay;
late String _light_mode;
late String _relay_status_1;
late String _relay_status_2;
late String _relay_status_3;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'switch_1') {
_firstSwitch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'switch_2') {
_secondSwitch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'switch_3') {
_thirdSwitch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'countdown_1') {
_firstCount = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'countdown_2') {
_secondCount = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'countdown_3') {
_thirdCount = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status') {
_relay = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'light_mode') {
_light_mode = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status_1') {
_relay_status_1 = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status_2') {
_relay_status_2 = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status_3') {
_relay_status_3 = jsonList[i].value ?? 0;
}
}
return ThreeTouchModel(
firstSwitch: _firstSwitch,
secondSwitch: _secondSwitch,
thirdSwitch: _thirdSwitch,
firstCountDown: _firstCount,
secondCountDown: _secondCount,
thirdCountDown: _thirdCount,
light_mode: lightStatusExtension.fromString(_light_mode),
relay: StatusExtension.fromString(_relay),
relay_status_1: StatusExtension.fromString(_relay_status_1),
relay_status_2: StatusExtension.fromString(_relay_status_2),
relay_status_3: StatusExtension.fromString(_relay_status_3));
}
}

View File

@ -0,0 +1,63 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class TwoTouchModel {
bool firstSwitch;
bool secondSwitch;
int firstCountDown;
int secondCountDown;
status relay;
lightStatus light_mode;
status relay_status_1;
status relay_status_2;
TwoTouchModel(
{required this.firstSwitch,
required this.secondSwitch,
required this.firstCountDown,
required this.secondCountDown,
required this.light_mode,
required this.relay,
required this.relay_status_1,
required this.relay_status_2});
factory TwoTouchModel.fromJson(List<StatusModel> jsonList) {
late bool _firstSwitch;
late bool _secondSwitch;
late int _firstCount;
late int _secondCount;
late String _relay;
late String _light_mode;
late String _relay_status_1;
late String _relay_status_2;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'switch_1') {
_firstSwitch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'switch_2') {
_secondSwitch = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'countdown_1') {
_firstCount = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'countdown_2') {
_secondCount = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status') {
_relay = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'light_mode') {
_light_mode = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status_1') {
_relay_status_1 = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'relay_status_2') {
_relay_status_2 = jsonList[i].value ?? 0;
}
}
return TwoTouchModel(
firstSwitch: _firstSwitch,
secondSwitch: _secondSwitch,
firstCountDown: _firstCount,
secondCountDown: _secondCount,
light_mode: lightStatusExtension.fromString(_light_mode),
relay: StatusExtension.fromString(_relay),
relay_status_1: StatusExtension.fromString(_relay_status_1),
relay_status_2: StatusExtension.fromString(_relay_status_2));
}
}

View File

@ -0,0 +1,28 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class WaterLeakModel {
String waterContactState;
int batteryPercentage;
WaterLeakModel({
required this.waterContactState,
required this.batteryPercentage,
});
factory WaterLeakModel.fromJson(List<StatusModel> jsonList) {
late String _waterContactState;
late int _batteryPercentage;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'watersensor_state') {
_waterContactState = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'battery_percentage') {
_batteryPercentage = jsonList[i].value ?? 0;
}
}
return WaterLeakModel(
waterContactState: _waterContactState,
batteryPercentage: _batteryPercentage,
);
}
}

View File

@ -86,6 +86,8 @@ class ACsList extends StatelessWidget {
),
const SizedBox(height: 5),
DevicesDefaultSwitch(
off: 'OFF',
on: 'ON',
switchValue: devicesStatuesList[index].acSwitch,
action: () {
BlocProvider.of<ACsBloc>(context).add(AcSwitch(

View File

@ -22,6 +22,8 @@ class ACsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("ACsView deviceModel UUID: ${deviceModel?.uuid}");
return BlocProvider(
create: (context) => ACsBloc(acId: deviceModel?.uuid ?? '')
..add(AcsInitial(allAcs: deviceModel != null ? false : true)),
@ -66,12 +68,14 @@ class ACsView extends StatelessWidget {
child: state is AcsLoadingState
? const Center(
child: DefaultContainer(
width: 50, height: 50, child: CircularProgressIndicator()),
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
BlocProvider.of<ACsBloc>(context)
.add(AcsInitial(allAcs: deviceModel != null ? false : true));
BlocProvider.of<ACsBloc>(context).add(AcsInitial(
allAcs: deviceModel != null ? false : true));
},
child: Container(
padding: const EdgeInsets.only(top: 40),

View File

@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class CircularButton extends StatelessWidget {
const CircularButton({
super.key,
required this.device,
required this.label,
required this.onTap,
required this.icons,
});
final DeviceModel? device;
final String label;
final Function()? onTap;
final IconData icons;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Card(
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
),
child: GestureDetector(
onTap: onTap,
child: Stack(
alignment: Alignment.center,
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(100),
),
),
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
),
child: Center(
child: label == 'All On'
? BodySmall(
text: "On",
style: context.bodyMedium.copyWith(
color: ColorsManager.primaryColorWithOpacity,
fontWeight: FontWeight.bold),
)
: label == 'All Off'
? BodySmall(
text: "Off",
style: context.bodyMedium.copyWith(
color:
ColorsManager.primaryColorWithOpacity,
fontWeight: FontWeight.bold),
)
: Icon(
icons,
color: ColorsManager.primaryColorWithOpacity,
size: 25,
),
),
),
],
),
),
),
const SizedBox(height: 10),
BodySmall(
// text: "Timer",
text: label,
style: context.bodyMedium.copyWith(
color: ColorsManager.textPrimaryColor,
),
),
],
);
}
}

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
@ -17,8 +16,8 @@ class CurtainButtons extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildButton(
onTap: () => context.read<CurtainBloc>().add(OpenCurtain(curtain.productType!)),
iconPath: Assets.assetsIconsCurtainsIconOpenCurtain,
onTap: () => context.read<CurtainBloc>().add(CloseCurtain(curtain.productType!)),
iconPath: Assets.assetsIconsCurtainsIconCloseCurtain,
),
_buildButton(
onTap: () => context.read<CurtainBloc>().add(PauseCurtain()),
@ -26,8 +25,8 @@ class CurtainButtons extends StatelessWidget {
isSvg: false,
),
_buildButton(
onTap: () => context.read<CurtainBloc>().add(CloseCurtain(curtain.productType!)),
iconPath: Assets.assetsIconsCurtainsIconCloseCurtain,
onTap: () => context.read<CurtainBloc>().add(OpenCurtain(curtain.productType!)),
iconPath: Assets.assetsIconsCurtainsIconOpenCurtain,
),
],
);

Some files were not shown because too many files have changed in this diff Show More