From 1b4073f6900e652679f38131f4b9f0140bf3c2a3 Mon Sep 17 00:00:00 2001 From: Akira Date: Tue, 9 Apr 2024 01:58:25 +0900 Subject: [PATCH] =?UTF-8?q?=E6=9C=AA=E7=A2=BA=E8=AA=8D=E3=81=A0=E3=81=8C?= =?UTF-8?q?=E5=95=8F=E9=A1=8C=E5=9B=9E=E9=81=BF=E3=81=AE=E3=81=9F=E3=82=81?= =?UTF-8?q?=E3=83=97=E3=83=83=E3=82=B7=E3=83=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/customIcon/SVG/gps_signal_high.svg | 262 ++++++++++++++ assets/customIcon/SVG/gps_signal_low.svg | 330 ++++++++++++++++++ assets/customIcon/SVG/gps_signal_middle.svg | 223 ++++++++++++ assets/customIcon/gps_signal.psd | Bin 0 -> 163902 bytes assets/customIcon/gps_signal_high.png | Bin 0 -> 5694 bytes assets/customIcon/gps_signal_low.png | Bin 0 -> 6665 bytes assets/customIcon/gps_signal_middle.png | Bin 0 -> 5547 bytes assets/customIcon/icomoon-old/Read Me.txt | 7 + .../icomoon-old/demo-files/demo.css | 152 ++++++++ .../customIcon/icomoon-old/demo-files/demo.js | 30 ++ assets/customIcon/icomoon-old/demo.html | 80 +++++ .../customIcon/icomoon-old/fonts/icomoon.eot | Bin 0 -> 5148 bytes .../customIcon/icomoon-old/fonts/icomoon.svg | 39 +++ .../customIcon/icomoon-old/fonts/icomoon.woff | Bin 0 -> 5060 bytes assets/customIcon/icomoon-old/selection.json | 1 + assets/customIcon/icomoon-old/style.css | 169 +++++++++ assets/customIcon/icomoon.zip | Bin 0 -> 97487 bytes assets/customIcon/icomoon/Read Me.txt | 7 + assets/customIcon/icomoon/demo-files/demo.css | 152 ++++++++ assets/customIcon/icomoon/demo-files/demo.js | 30 ++ assets/customIcon/icomoon/demo.html | 80 +++++ assets/customIcon/icomoon/fonts/icomoon.eot | Bin 0 -> 8328 bytes assets/customIcon/icomoon/fonts/icomoon.svg | 50 +++ assets/customIcon/icomoon/fonts/icomoon.ttf | Bin 0 -> 8164 bytes assets/customIcon/icomoon/fonts/icomoon.woff | Bin 0 -> 8240 bytes assets/customIcon/icomoon/selection.json | 1 + assets/customIcon/icomoon/style.css | 224 ++++++++++++ assets/fonts/icomoon.ttf | Bin 0 -> 8164 bytes lib/data/location_data.dart | 1 + lib/main.dart | 74 ++++ lib/model/auth_user.dart | 3 + lib/model/destination.dart | 3 + lib/pages/camera/camera_page.dart | 6 + .../change_password_page_controller.dart | 0 .../destination/destination_controller.dart | 214 +++++++++--- lib/pages/destination/destination_page.dart | 252 ------------- .../destination_map_controller.dart | 0 .../destination_map/destination_map_page.dart | 4 + lib/pages/drawer/drawer_binding.dart | 0 lib/pages/drawer/drawer_page.dart | 6 + lib/pages/gps/gps_page.dart | 4 + lib/pages/history/history_page.dart | 3 + lib/pages/home/home_page.dart | 2 + lib/pages/index/index_controller.dart | 68 ++-- lib/pages/index/index_page.dart | 3 + lib/pages/landing/landing_page.dart | 3 + lib/pages/loading/loading_page.dart | 2 + lib/pages/login/login_page.dart | 4 + lib/pages/login_popup/login_popup_page.dart | 4 + lib/pages/permission/permission.dart | 4 + lib/services/auth_service.dart | 39 ++- lib/services/device_info_service.dart | 2 +- lib/services/error_service.dart | 14 +- lib/services/external_service.dart | 99 +++--- lib/utils/location_controller.dart | 36 +- lib/widgets/custom_icons.dart | 9 + lib/widgets/gps_status.dart | 8 +- lib/widgets/map_widget.dart | 84 ++++- pubspec.yaml | 6 + 59 files changed, 2384 insertions(+), 410 deletions(-) create mode 100644 assets/customIcon/SVG/gps_signal_high.svg create mode 100644 assets/customIcon/SVG/gps_signal_low.svg create mode 100644 assets/customIcon/SVG/gps_signal_middle.svg create mode 100644 assets/customIcon/gps_signal.psd create mode 100644 assets/customIcon/gps_signal_high.png create mode 100644 assets/customIcon/gps_signal_low.png create mode 100644 assets/customIcon/gps_signal_middle.png create mode 100644 assets/customIcon/icomoon-old/Read Me.txt create mode 100644 assets/customIcon/icomoon-old/demo-files/demo.css create mode 100644 assets/customIcon/icomoon-old/demo-files/demo.js create mode 100644 assets/customIcon/icomoon-old/demo.html create mode 100644 assets/customIcon/icomoon-old/fonts/icomoon.eot create mode 100644 assets/customIcon/icomoon-old/fonts/icomoon.svg create mode 100644 assets/customIcon/icomoon-old/fonts/icomoon.woff create mode 100644 assets/customIcon/icomoon-old/selection.json create mode 100644 assets/customIcon/icomoon-old/style.css create mode 100644 assets/customIcon/icomoon.zip create mode 100644 assets/customIcon/icomoon/Read Me.txt create mode 100644 assets/customIcon/icomoon/demo-files/demo.css create mode 100644 assets/customIcon/icomoon/demo-files/demo.js create mode 100644 assets/customIcon/icomoon/demo.html create mode 100644 assets/customIcon/icomoon/fonts/icomoon.eot create mode 100644 assets/customIcon/icomoon/fonts/icomoon.svg create mode 100644 assets/customIcon/icomoon/fonts/icomoon.ttf create mode 100644 assets/customIcon/icomoon/fonts/icomoon.woff create mode 100644 assets/customIcon/icomoon/selection.json create mode 100644 assets/customIcon/icomoon/style.css create mode 100644 assets/fonts/icomoon.ttf delete mode 100644 lib/pages/changepassword/change_password_page_controller.dart delete mode 100644 lib/pages/destination/destination_page.dart delete mode 100644 lib/pages/destination_map/destination_map_controller.dart delete mode 100644 lib/pages/drawer/drawer_binding.dart create mode 100644 lib/widgets/custom_icons.dart diff --git a/assets/customIcon/SVG/gps_signal_high.svg b/assets/customIcon/SVG/gps_signal_high.svg new file mode 100644 index 0000000..f218fb8 --- /dev/null +++ b/assets/customIcon/SVG/gps_signal_high.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/customIcon/SVG/gps_signal_low.svg b/assets/customIcon/SVG/gps_signal_low.svg new file mode 100644 index 0000000..366fade --- /dev/null +++ b/assets/customIcon/SVG/gps_signal_low.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/customIcon/SVG/gps_signal_middle.svg b/assets/customIcon/SVG/gps_signal_middle.svg new file mode 100644 index 0000000..d7ec422 --- /dev/null +++ b/assets/customIcon/SVG/gps_signal_middle.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/customIcon/gps_signal.psd b/assets/customIcon/gps_signal.psd new file mode 100644 index 0000000000000000000000000000000000000000..f769c9f0fdc71620b9930c393e43668d165245db GIT binary patch literal 163902 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 +
+

Font Test Drive

+ + +
  +
+
+ +
+

Generated by IcoMoon

+
+ + + + diff --git a/assets/customIcon/icomoon-old/fonts/icomoon.eot b/assets/customIcon/icomoon-old/fonts/icomoon.eot new file mode 100644 index 0000000000000000000000000000000000000000..74b0f408edcbebfa401d38c0549094e24c4cd443 GIT binary patch literal 5148 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 + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/customIcon/icomoon-old/fonts/icomoon.woff b/assets/customIcon/icomoon-old/fonts/icomoon.woff new file mode 100644 index 0000000000000000000000000000000000000000..351d4f9b45794e232bf7b841557b600c4eea3360 GIT binary patch literal 5060 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 OA1I#v`}0@0@_ztpA*T)i literal 0 HcmV?d00001 diff --git a/assets/customIcon/icomoon/Read Me.txt b/assets/customIcon/icomoon/Read Me.txt new file mode 100644 index 0000000..723a49e --- /dev/null +++ b/assets/customIcon/icomoon/Read Me.txt @@ -0,0 +1,7 @@ +Open *demo.html* to see a list of all the glyphs in your font along with their codes/ligatures. + +To use the generated font in desktop programs, you can install the TTF font. In order to copy the character associated with each icon, refer to the text box at the bottom right corner of each glyph in demo.html. The character inside this text box may be invisible; but it can still be copied. See this guide for more info: https://icomoon.io/docs/#local-fonts + +You won't need any of the files located under the *demo-files* directory when including the generated font in your own projects. + +You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection. diff --git a/assets/customIcon/icomoon/demo-files/demo.css b/assets/customIcon/icomoon/demo-files/demo.css new file mode 100644 index 0000000..39b8991 --- /dev/null +++ b/assets/customIcon/icomoon/demo-files/demo.css @@ -0,0 +1,152 @@ +body { + padding: 0; + margin: 0; + font-family: sans-serif; + font-size: 1em; + line-height: 1.5; + color: #555; + background: #fff; +} +h1 { + font-size: 1.5em; + font-weight: normal; +} +small { + font-size: .66666667em; +} +a { + color: #e74c3c; + text-decoration: none; +} +a:hover, a:focus { + box-shadow: 0 1px #e74c3c; +} +.bshadow0, input { + box-shadow: inset 0 -2px #e7e7e7; +} +input:hover { + box-shadow: inset 0 -2px #ccc; +} +input, fieldset { + font-family: sans-serif; + font-size: 1em; + margin: 0; + padding: 0; + border: 0; +} +input { + color: inherit; + line-height: 1.5; + height: 1.5em; + padding: .25em 0; +} +input:focus { + outline: none; + box-shadow: inset 0 -2px #449fdb; +} +.glyph { + font-size: 16px; + width: 15em; + padding-bottom: 1em; + margin-right: 4em; + margin-bottom: 1em; + float: left; + overflow: hidden; +} +.liga { + width: 80%; + width: calc(100% - 2.5em); +} +.talign-right { + text-align: right; +} +.talign-center { + text-align: center; +} +.bgc1 { + background: #f1f1f1; +} +.fgc1 { + color: #999; +} +.fgc0 { + color: #000; +} +p { + margin-top: 1em; + margin-bottom: 1em; +} +.mvm { + margin-top: .75em; + margin-bottom: .75em; +} +.mtn { + margin-top: 0; +} +.mtl, .mal { + margin-top: 1.5em; +} +.mbl, .mal { + margin-bottom: 1.5em; +} +.mal, .mhl { + margin-left: 1.5em; + margin-right: 1.5em; +} +.mhmm { + margin-left: 1em; + margin-right: 1em; +} +.mls { + margin-left: .25em; +} +.ptl { + padding-top: 1.5em; +} +.pbs, .pvs { + padding-bottom: .25em; +} +.pvs, .pts { + padding-top: .25em; +} +.unit { + float: left; +} +.unitRight { + float: right; +} +.size1of2 { + width: 50%; +} +.size1of1 { + width: 100%; +} +.clearfix:before, .clearfix:after { + content: " "; + display: table; +} +.clearfix:after { + clear: both; +} +.hidden-true { + display: none; +} +.textbox0 { + width: 3em; + background: #f1f1f1; + padding: .25em .5em; + line-height: 1.5; + height: 1.5em; +} +#testDrive { + display: block; + padding-top: 24px; + line-height: 1.5; +} +.fs0 { + font-size: 16px; +} +.fs1 { + font-size: 32px; +} + diff --git a/assets/customIcon/icomoon/demo-files/demo.js b/assets/customIcon/icomoon/demo-files/demo.js new file mode 100644 index 0000000..6f45f1c --- /dev/null +++ b/assets/customIcon/icomoon/demo-files/demo.js @@ -0,0 +1,30 @@ +if (!('boxShadow' in document.body.style)) { + document.body.setAttribute('class', 'noBoxShadow'); +} + +document.body.addEventListener("click", function(e) { + var target = e.target; + if (target.tagName === "INPUT" && + target.getAttribute('class').indexOf('liga') === -1) { + target.select(); + } +}); + +(function() { + var fontSize = document.getElementById('fontSize'), + testDrive = document.getElementById('testDrive'), + testText = document.getElementById('testText'); + function updateTest() { + testDrive.innerHTML = testText.value || String.fromCharCode(160); + if (window.icomoonLiga) { + window.icomoonLiga(testDrive); + } + } + function updateSize() { + testDrive.style.fontSize = fontSize.value + 'px'; + } + fontSize.addEventListener('change', updateSize, false); + testText.addEventListener('input', updateTest, false); + testText.addEventListener('change', updateTest, false); + updateSize(); +}()); diff --git a/assets/customIcon/icomoon/demo.html b/assets/customIcon/icomoon/demo.html new file mode 100644 index 0000000..81d22fa --- /dev/null +++ b/assets/customIcon/icomoon/demo.html @@ -0,0 +1,80 @@ + + + + + IcoMoon Demo + + + + + +
+

Font Name: icomoon (Glyphs: 3)

+
+
+

Grid Size: Unknown

+
+
+ + icon-gps_signal_low +
+
+ + +
+
+ liga: + +
+
+
+
+ + icon-gps_signal_middle +
+
+ + +
+
+ liga: + +
+
+
+
+ + icon-gps_signal_high +
+
+ + +
+
+ liga: + +
+
+
+ + +
+

Font Test Drive

+ + +
  +
+
+ +
+ + + + diff --git a/assets/customIcon/icomoon/fonts/icomoon.eot b/assets/customIcon/icomoon/fonts/icomoon.eot new file mode 100644 index 0000000000000000000000000000000000000000..ef25f06322f7448841b7917a9089289cc66a1309 GIT binary patch literal 8328 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 literal 0 HcmV?d00001 diff --git a/assets/customIcon/icomoon/fonts/icomoon.svg b/assets/customIcon/icomoon/fonts/icomoon.svg new file mode 100644 index 0000000..aeaaed4 --- /dev/null +++ b/assets/customIcon/icomoon/fonts/icomoon.svg @@ -0,0 +1,50 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/customIcon/icomoon/fonts/icomoon.ttf b/assets/customIcon/icomoon/fonts/icomoon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f2e8bb498da09a4406f059d856e8888f7e7c72bd GIT binary patch literal 8164 zcmd5>d5k1ieXjTFcy)ADb$3;FRiD$>^xZu@ea`OAv3Sp!o!wz)y$4AQB95P!bZ6Kdc0y1d#|4DT#y>AtI!ZM2V0{B4Ogq_o}+b z1KCLYnVvr0t9td`@BY5`Mj(P97{W7xDD<|@EcETTatBxb6rW319>09sJNMnM2m;BX z|KOvSpSX?RDEjL~rzI*{KA%{7HS03BBa`~k%zIYt{SJ8jy@yqYIE%b%22|}K)SGaZg@oS&i z&|X7-8EZU$d*_L}kQ1-DZ}9tqC>6=a1X&R1XXv+a<)h&*`4?e8G(K+6i|{3X?sZTQ zepC}*z4xkcP{arKxGiR{LeSu=@lO`_!e22Ml@%mm3D6Qy#gP%f3H_q;sulHpf!vPvf7$+*@fwJQGj4^x;$@D=`e^7GFs)D)>f&UFM6I&MU9^9cDoOE zx}9g9dFGygukG#a&!5>o^L?+II5L@RrF<=t&fMPKzIu3V^<9I0yX5(4N>ygr-F&{< z>~t;-2jjr<_g-jt@7RRl#ZPnHy z8B0=SD`(4iP^7ZP2q6{G>!n2|JGF#jX{~eZ-eB;~efyRlm`u*(a(0B!TsBkJZnV*)c{i?V2Vk>x^xluGL-E?oH1=E*_hOp95nnTd+3WaVO#E>lUAHHlDSP_LH~ zRS4-aTWy|eH?o;5A+h+}+=Zp3!~4eL>kGY3Bxz7tv~#uuA=l=RQ9)jaXAuXy4!}XM ze+j{w#M?tRjA8hb8=n6q5$oYFd|QZoevA8wz5oLqe0sHhNRzQm0n%TMB znaSjV<$e3!IT-ZX=iBw|PIWb>nz|lWD-ZUZN}L{YYH=8QRQCs|>XEFGh;(`j*T>_1 zhnJQv%+1APgg~Q4`&=UxV{+bOj%hHpm{Y|#+tuT*p~pVx0bzL{29c!jK*WVS8T7sV z_?q;g#;`W5maC<5a05f31g_NRpEu98#>FDb=hu&(JO9e*?G?i}&7?6|TH0BfEDeuC z#*O`@BV{vf%S=?FR1}FW(o>D?#^B`Umo8j5v0f^XLSdQP8sW1(O!d?I)`^)msX`D` zN|Z@V;>C>DnpeelK<1-B31L2v1%ix*K>%diO%Ma3#FQgW+W?2mL+OMtf)jWpC+@os4I-kB@$^SN}?DwwYVr!N_7b?V~(iH z<}6NV6E-h~@s2tL?W;WGxiNy!4sAUcCkM3YFQi1n(xO^vza5iZs)#5LF^?W-?SJwB z`Juny+t5uWaw?tMMunzU&T?w0>?G4#AwZeR#N^1c>k$9Q4P0kuE_Da#xP~ zaAhLt!dqp9yRyn%i5sKH;!c<>KF9YgT#OZQX5b?6T>2k;)qLq89B63{=?+=BjLf(NNhKj>7P-h&l2uIr|n zTdj7stBR@8!%AFKb48UIro+6v%wlQP-pxJoEzD`mY6v0?)+FC5tQ8%2rR=+P^6cE& zT(Y0`vLZD@yU-;(lgBfqDla-blBdN5@PR4d0qzjmT7GhW>j3p^sz^CUq(oK^)mNWh zqf8<{BxI$PnPgKn7bP=$q?#J|^$`MBR(X0d`?EykTk%@YTg7 zcqK3b2J8>=48|!{d4ZrMEvlwd#P_Ya81jK&b|UG>W;0O&_OsJgoQx$|J zRe2O^m5mxjfJ&O|R$VH3@t8{~hC;MZw!m)O2D?!hgdl=4v>^m$Zf`)o<0v0aFjDXyRmVZleqGXF zBcm9t0L>ITZOSH9qufGAkU%h2$x=`^WyX^mr6!Vw`Q%+W$t#dEf;Ey#Siu<2gx`)b ziiy$|K$a|O>4>P|VG^C=^fUDHckrAQ$i|%v!C=%?LjO!c(Ln)HL?$UV-9+55r~T1bU1C1bQC{PjB938L_uWfL}HFHMF(EW8YZSv6y*~| zR%Vr?5d*2`cocHql5j*2;GV&ju1 zHa2Fw_rQSz?>?|hHeKC__j)g$KY!`Q*>iV1FKIU$Pi=0V&F#+|9F5MEivAJMTf#Xm zUIEu7*Z1FDe*5Oh8@{jUqv7YSJaYZ$;lnq<;3)i>&YbM`SK$NXJ#h6W@IeX4dR_Q6 zcp_xq2nnVH^44Z_mlu6-8imQI%Lp?t161Ww4e9|^r$uR2wVm#i@N$<0#3#@$5|C7`( zJ>VRJ93P;n-wr9q#&V<4JkxBpV(o_(25*^H4P>iYYBnx*x(%lkLm5^imK@JjldWXu zOxca-F;~wXDmRYhC7Vf7blxR})&AniOxji?3U+hz@ZqD^AGz|m;Yinf|HjG9x1+{> z7Yl1b9JdI=8c|khX{tHhyVAeHdT-R&Y8bKs zl?#BH$1Hu$nU4YpY$<=NQ9hK_-IyM6%V#>tmPhZJz9l*;Xn3|rfLm(PR+F)OS|k>b zC(IAdJIlg@!VAK0z%QU7h~0o=4#ojRnQ}`IlBv%)-vnavA_htwL_g%<`#h9do(H^$ zjfW$+Fu>5kWS52ph|3q?-s4a5cJM}iig0SF}Znfhhbk<%V zx~l_+EOpL~37M>T4C@_&qekM{>#NqWpyb@>KX$+FTgui;|z`WR~z(83LgDJ>`R%Ebf zSbYLt@a(}3hkQmgfd@`CL1c0ML?)#;&Su**B#4)qm%vTb6M0c0N<<-D$O{{aDv8ld z>OvtOhei=eqa^D?%ThKD=!D)gUR#As1IQFQ5vdVM@XPp}e%x$lwU`>!WoJHarzlNC z;RPEc$%rJ*xL~h|x~s-y1t<@{Wz4w*CC{Zj31nN08aN6eRxA!|Q$*Q`MKcCWD%!H7 zQliLmj4^DXWlmVbeHPt;thSJXw1~!C=7;hOp?M#1Nq1u1b!I5VLup5=7hCg`e7M(T zaKqsGP*lpkXKPN~VaZZh7wB6tCx8?CW}Z4gdt8}s73(^AqL^S9s@YiZ4O}e?=YA<% zEps+Fdk3^3_ySPz1e*TL5SHf?+VoeqwzfWdYU|VtXeX1&E#L=vKb5IcNY`&3I`-1W z=?@G`zMmGU#w-hG1m#+@`A}~GyYkklayg%K-L%5U|3Y3GwF}YSh1$wn^Lg8jo_~J;(9DWTp>O=3Rgii`MyWB1qCMm z-a?1({`vlFf`fx~vavE6joyKeo-n&M#W|BwYcwt_Ec91zbu@*kE=V)&+*;lK#6i_J zj~#gKYHyH`E5@!5$4$6jo*9NZzp7tGD|0a z(P}ogDsV(D*Rm`H8-|SM!A-^E^?GYG=wE7gnr}KCwe5WVtt+()y=Wo+`gdXn`+m>o zyT$b(8mk+ShRUj|E4o}vCVjwqWT^uwHHO16(jF*UXGztS*kavaoq1*(nyhMZmUmU9 zh}4c?cXX2~w1Q;Hn<8EjMbf0jjHl%+$;AdA;L3C3Rq<)WNLe@p9D;-XPl|y3F-M>I zkf`0C8{nRpHxl~P)GHf-3nszY4K(ZaUjO|QpWfs+zq&9+f*?t{L8o|V9y=bgvAWj= z{evjXD_xMXU{E(TNG+`H;RR zNCJ-g#_~x|RCU)fJ!5XYIl0=6Bn&NX=$cx)I6C?K0s121Fan?}Dyo}jaZQyq!)Egx zX4L!B`t~tOcCREn87Nr6x3R4Uw5RJ!?D=iNqJkK`k+d6D@ENRZ(KhttWBTl{lHO zEWYKo^H#*RBeEgK$_^E!?3O=oMAKf+2N%hWoi8AA5r<(wriZES3RyOoK{Uw;_=e%A zvQEu-Dz_0sRAG0m+1Tt+wOA=#bY7mTfq%$iG+-k*s14Xil-OD(9!tuSBH`rBwD^%S zPLo-TnxwKix4^Jlo?IW`pq4OxY#heNjFZgoJ*=381+T1}5LP)Mgd=wui$!YWOeY?R zJkWqmOeO;7wS=0|qtOd5W&6l5ab>OlfrM>mWjw1fAAe#+a*N+Na2F_@ow!OGkG zz{axR9-QeU>n@8aiV8wv=B&AdPCiwd1>1in5jq=C!ki6oXRm0 zuQ-G26PzrwUf~!-luS3C(x*P67hw;6mI8JLz2OKPLef>&!nVH}Nn7L-S}N|E5~7e7 zwxGBP!V{PN>F?fdFaL*N@Iy2~_`yB}=NYr#=_vvJPs#NNUU)9}f1e;NpgO%K4QDe= z?+ZdZoGI+{$N0$q&!0e2U2stWKTbYHeo7w{E%B)M5%G`3@509qN*|J5mi|HdsqD*5 zc~$;RMNq!Us_bp-W9kj{tD36ywd2}1^uIOw#%<%bjK7b3HS#la+kDpi9A@TrZVP|N zITBtoD+ZnEmnD2_?F5>!l+Lq9Ma@v-04x5;^6_z?e} zsifhGg*#!JqW$Q!Euy_LZA)msZ`ziHq)?c)60e zj|rEBJNF%Vbm!LH!lT!2UAuGn?zO9hN1iIIU)ebc*}6Ch;%nc<>W^ZYTY*HE(Z42K b#kEJkPYc3&puovc0mvBqpLDNNezE;O{)`jr literal 0 HcmV?d00001 diff --git a/assets/customIcon/icomoon/fonts/icomoon.woff b/assets/customIcon/icomoon/fonts/icomoon.woff new file mode 100644 index 0000000000000000000000000000000000000000..4ed8b4efbda6fdbde1aea90e1dfd4ba1f956253e GIT binary patch literal 8240 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 literal 0 HcmV?d00001 diff --git a/assets/customIcon/icomoon/selection.json b/assets/customIcon/icomoon/selection.json new file mode 100644 index 0000000..de89dcd --- /dev/null +++ b/assets/customIcon/icomoon/selection.json @@ -0,0 +1 @@ +{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M4.697 371.083c0-123.694 0-245.040 0-366.385 356.991-0 713.982-0 1070.972-0 0 341.333 0 682.667 0 1024-356.991 0-713.982 0-1070.972 0-0-218.422-0-436.844-0-657.615zM54.676 595.488c8.121 29.927 13.467 60.954 24.814 89.603 73.114 184.603 210.166 292.309 405.758 315.852 266.402 32.066 503.041-151.136 541.779-416.589 26.568-182.062-36.314-334.611-177.010-450.896-110.474-91.306-241.173-124.942-383.508-103.957-127.29 18.767-232.431 79.646-312.212 180.371-88.664 111.94-121.433 240.139-99.62 385.616z","M54.001 593.523c-21.138-143.512 11.63-271.711 100.295-383.651 79.781-100.726 184.922-161.605 312.212-180.371 142.335-20.985 273.035 12.651 383.508 103.957 140.696 116.285 203.578 268.833 177.010 450.896-38.737 265.453-275.376 448.655-541.779 416.589-195.592-23.543-332.644-131.249-405.758-315.852-11.347-28.649-16.693-59.676-25.488-91.568zM493.216 582.955c0 0-1.199 1.237-4.108 3.501-15.138 15.638-30.275 31.276-47.497 49.623-6.517 6.27-13.034 12.539-22.199 19.893-20.165 20.664-40.33 41.329-62.409 64.715-4.767 4.63-9.535 9.261-17.027 14.967-17.098 17.578-34.196 35.156-53.412 55.506-3.397 3.166-6.794 6.333-12.766 10.681-15.251 15.398-30.503 30.797-45.735 46.176 161.781 159.584 456.337 177.301 643.164-16.003 193.416-200.12 149.585-488.401 5.346-626.396-56.661 54.941-113.278 109.839-171.898 167.468-9.587 9.377-19.174 18.754-31.401 29.287-17.031 17.498-34.062 34.995-53.17 55.23-4.967 4.743-9.934 9.485-17.489 15.395-18.525 19.010-37.051 38.020-57.67 59.748-6.536 6.316-13.073 12.632-21.576 19.475-1.581 2.108-3.163 4.216-6.521 9.011-6.080 5.961-12.16 11.922-20.487 18.182-1.455 0.761-2.314 1.951-2.211 3.625 0 0 0.034 0.37-0.935-0.085zM457.349 571.913c0 0-0.712 0.977 2.256-1.469 31.315-31.739 62.63-63.477 97.020-96.279 4.189-4.859 8.378-9.717 15.274-15.85 25.278-25.754 50.555-51.508 78.782-78.569 8.838-9.388 17.677-18.776 29.227-29.44 57.003-56.719 114.006-113.437 173.154-172.291-127.777-109.386-271.643-148.812-430.725-105.427-177.884 48.513-292.038 167.261-331.848 348.107-33.559 152.449 8.712 287.734 114.173 407.397 13.331-16.326 24.48-29.98 38.474-44.797 3.774-2.991 7.548-5.982 14.040-10.238 18.934-19.42 37.868-38.839 59.863-59.322 4.17-4.831 8.339-9.662 15.251-15.732 41.798-42.129 83.596-84.258 125.060-126.090z","M647.731 381.052c-25.278 25.754-50.555 51.508-78.41 76.23-85.383-1.219-168.198-2.262-250.989-1.289-54.246 0.638-104.545 39.561-115.433 92.715-6.635 32.394-3.208 66.74-5.864 100.084-4.093 51.377 6.421 97.585 43.256 135.665-11.149 13.654-22.298 27.308-35.629 43.635-105.46-119.663-147.732-254.948-114.173-407.397 39.81-180.846 153.964-299.594 331.848-348.107 159.081-43.385 302.948-3.959 430.725 105.427-59.149 58.854-116.151 115.572-175.322 171.472-52.719-33.54-106.686-44.272-167.197-35.86-49.736 6.914-90.483 28.306-128.083 58.454-11.706 9.386-24.523 22.034-10.979 38.809 12.334 15.278 25.445 6.171 35.552-3.391 47.505-44.942 103.381-65.857 167.97-54.371 25.104 4.464 48.535 18.337 72.729 27.924z","M706.678 370.357c56.617-54.898 113.234-109.796 169.895-164.737 144.239 137.995 188.070 426.275-5.346 626.396-186.827 193.303-481.382 175.587-643.164 16.003 15.232-15.379 30.484-30.777 48.077-45.472 16.687 3.827 31.019 9.601 45.377 9.666 148.48 0.671 296.967 0.883 445.447 0.224 69.745-0.309 124.21-55.525 125.408-125.287 0.577-33.594 0.331-67.208 0.085-100.81-0.56-76.639-54.843-130.298-131.996-130.73-46.094-0.258-92.187-0.496-138.281-0.743 17.031-17.498 34.062-34.995 53.601-52.013 6.812 3.35 10.774 7.623 15.497 8.774 7.82 1.905 21.142 5.075 23.229 1.883 4.929-7.54 6.615-18.719 5.65-28.014-0.567-5.454-8.732-10.12-13.479-15.14z","M288.683 788.389c17.098-17.578 34.196-35.156 54.055-52.173 25.691 0.936 49.255 4.88 71.414 0.931 43.88-7.82 43.56-9.622 43.559-53.704-0-12.444 1.298-25.097-0.649-37.229-0.782-4.871-8.698-8.597-13.367-12.844 15.138-15.638 30.275-31.276 47.258-47.226 1.845-0.312 3.424-1.259 3.58 1.081 0.156 51.265 0.156 100.191 0.156 149.031 10.116 0 17.547 0 26.374 0 0-12.799 0-24.391 0-35.982 0-12.228 0-24.456 0-35.717 22.424-2.396 42.894-2.377 62.18-7.144 31.628-7.817 48.024-32.983 47.054-66.477-0.906-31.284-17.309-50.117-50.913-57.192-10.573-2.226-21.551-2.53-32.344-3.714 18.525-19.010 37.051-38.020 58.45-56.409 55.319 0.696 107.77 0.285 160.207 0.974 60.482 0.795 106.686 46.886 107.85 107.17 0.605 31.3 0.184 62.62 0.12 93.931-0.152 73.981-44.235 118.075-118.264 118.112-138.552 0.068-277.104 0.207-415.655-0.22-17.027-0.052-34.044-3.385-51.065-5.197zM685.514 536.493c-9.389 11.917-22.983 22.491-27.307 36.027-9.514 29.78 6.364 55.983 37.202 65.543 19.283 5.977 39.588 8.571 59.224 13.52 14.668 3.697 25.308 11.705 25.972 28.854 0.681 17.589-8.526 28.124-23.865 33.383-8.692 2.98-18.715 5.807-27.408 4.348-24.887-4.178-49.4-10.58-78.679-17.143 5.071 9.826 7.662 24.504 15.266 27.874 29.575 13.11 61.062 18.449 93.416 8.941 29.759-8.745 48.729-31.477 48.58-58.593-0.153-27.827-15.741-45.238-49.196-53.785-15.864-4.053-32.090-6.666-48.039-10.411-17.044-4.002-31.058-15.2-27.148-32.21 2.68-11.657 15.84-25.504 27.342-29.37 14.379-4.833 32.251-2.436 47.889 0.59 13.633 2.638 26.26 10.48 39.331 16.022 1.731-1.056 3.462-2.112 5.193-3.168-4.75-9.855-7.118-25.43-14.664-28.573-32.18-13.401-65.977-19.331-103.108-1.85z","M553.549 475.228c-31.315 31.739-62.63 63.477-95.517 94.277 4.048-19.731-3.166-30.462-22.079-34.436-11.364-2.388-22.431-6.401-33.866-8.2-45.115-7.097-87.371 11.223-106.921 45.699-22.276 39.283-18.799 104.031 7.602 135.059 2.749 3.23 7.425 4.821 11.207 7.172-18.934 19.42-37.868 38.839-58.357 57.246-21.783-25.020-39.474-50.197-39.474-83.5 0.001-36.655-0.838-73.334 0.222-109.958 1.634-56.438 47.027-102.894 103.262-103.688 77.956-1.101 155.944 0.109 233.919 0.329z","M287.624 789.775c18.081 0.427 35.098 3.759 52.124 3.812 138.55 0.427 277.103 0.289 415.655 0.22 74.029-0.037 118.112-44.131 118.264-118.112 0.064-31.311 0.485-62.632-0.12-93.931-1.164-60.285-47.368-106.376-107.85-107.17-52.437-0.689-104.888-0.278-158.913-1.557 3.386-5.947 8.354-10.689 14.359-16.801 47.132-1.122 93.226-0.884 139.32-0.626 77.153 0.432 131.437 54.090 131.996 130.73 0.245 33.602 0.492 67.216-0.085 100.81-1.198 69.762-55.663 124.978-125.408 125.287-148.48 0.659-296.967 0.447-445.447-0.224-14.358-0.065-28.691-5.839-44.090-10.257 2.342-4.461 5.739-7.628 10.196-12.179z","M649.206 380.399c-25.668-8.934-49.099-22.807-74.203-27.271-64.589-11.486-120.465 9.429-167.97 54.371-10.107 9.562-23.218 18.669-35.552 3.391-13.543-16.775-0.727-29.423 10.979-38.809 37.6-30.148 78.346-51.54 128.083-58.454 60.511-8.412 114.478 2.32 165.841 36.498-8.027 10.846-16.865 20.234-27.178 30.275z","M457.684 571.617c-41.798 42.129-83.596 84.258-127.487 125.542-26.108-30.178-27.734-63.581-17.936-98.031 8.9-31.292 33.578-51.725 65.771-48.569 26.979 2.645 53.133 13.717 79.652 21.058z","M555.087 474.696c-79.512 0.311-157.501-0.898-235.457 0.203-56.235 0.794-101.629 47.25-103.262 103.688-1.060 36.624-0.222 73.304-0.222 109.958-0.001 33.303 17.69 58.48 38.115 84.132-3.578 4.636-7.352 7.627-12.548 11.199-38.258-37.499-48.771-83.707-44.678-135.084 2.656-33.344-0.771-67.69 5.864-100.084 10.887-53.154 61.187-92.077 115.433-92.715 82.792-0.973 165.607 0.070 249.637 1.926-2.965 6.528-7.154 11.386-12.881 16.777z","M545.992 531.388c11.84-0.175 22.818 0.129 33.391 2.355 33.604 7.075 50.007 25.908 50.913 57.192 0.97 33.494-15.425 58.66-47.054 66.477-19.286 4.767-39.756 4.748-62.18 7.144 0 11.261 0 23.489 0 35.717 0 11.592 0 23.183 0 35.982-8.826 0-16.258 0-26.374 0 0-48.84 0-97.766-0.001-149.426-0.001-2.734-0.505-3.42-0.505-3.42s-0.034-0.37 1.059-0.011c1.85-1.188 2.607-2.735 3.365-4.282 6.080-5.961 12.16-11.922 20.248-17.625 2.008 25.676 2.008 51.094 2.008 77.932 17.043-0.788 31.148-0.143 44.792-2.347 26.442-4.272 39.396-20.134 38.472-44.438-0.849-22.312-15.605-35.775-42.153-38.187-12.196-1.108-24.425-1.849-36.638-2.756 6.536-6.316 13.073-12.632 20.656-20.308z","M457.516 571.765c-26.352-7.489-52.505-18.561-79.484-21.206-32.194-3.157-56.871 17.277-65.771 48.569-9.799 34.449-8.172 67.852 16.564 98.65-3.448 6.296-7.618 11.127-13.318 16.489-5.312-1.82-9.989-3.41-12.737-6.64-26.401-31.028-29.878-95.776-7.602-135.059 19.55-34.476 61.806-52.796 106.921-45.699 11.434 1.799 22.502 5.812 33.866 8.2 18.913 3.974 26.127 14.705 20.595 35.66 0.088 2.163 0.8 1.185 0.968 1.037z","M524.353 551.959c13.198 0.644 25.427 1.385 37.622 2.493 26.548 2.411 41.304 15.875 42.153 38.187 0.924 24.304-12.030 40.166-38.472 44.438-13.644 2.204-27.749 1.559-44.792 2.347 0-26.838 0-52.255-1.119-79.275 0.462-3.71 2.043-5.818 4.608-8.19z","M442.653 634.725c5.711 2.892 13.627 6.618 14.409 11.489 1.947 12.132 0.649 24.785 0.649 37.229 0.001 44.083 0.322 45.885-43.559 53.704-22.158 3.949-45.723 0.005-70.051-1.469 3.368-5.73 8.136-10.36 15.853-16.702 19.909-2.381 37.037-1.881 53.745-4.292 6.746-0.974 18.282-9.024 17.833-12.635-1.964-15.793 11.32-35.329-9.472-47.16 6.517-6.27 13.034-12.539 20.593-20.164z","M420.736 655.43c22.116 11.289 8.832 30.825 10.796 46.618 0.449 3.61-11.087 11.661-17.833 12.635-16.708 2.411-33.836 1.911-52.788 2.931 18.172-20.313 38.337-40.978 59.825-62.184z","M705.677 371.722c5.749 3.655 13.914 8.32 14.481 13.775 0.965 9.296-0.721 20.474-5.65 28.014-2.087 3.192-15.409 0.021-23.229-1.883-4.723-1.15-8.685-5.423-14.177-9.351 8.399-10.435 17.986-19.812 28.575-30.555z","M497.484 579.266c0.366 1.398-0.391 2.945-2.425 4.106-1.012-2.006-0.153-3.196 2.425-4.106z","M493.7 583.183c0.484 0.227 0.988 0.913 0.833 1.308s-1.735 1.341-2.125 0.521c-0.39-0.82 0.808-2.057 1.292-1.829z","M687.197 535.787c35.449-16.776 69.246-10.846 101.426 2.555 7.546 3.142 9.914 18.717 14.664 28.573-1.731 1.056-3.462 2.112-5.193 3.168-13.071-5.543-25.698-13.385-39.331-16.022-15.639-3.026-33.51-5.423-47.889-0.59-11.501 3.866-24.662 17.713-27.342 29.37-3.91 17.009 10.104 28.208 27.148 32.21 15.949 3.745 32.176 6.358 48.039 10.411 33.454 8.548 49.042 25.958 49.196 53.785 0.149 27.116-18.82 49.848-48.58 58.593-32.354 9.507-63.842 4.168-93.416-8.941-7.604-3.37-10.195-18.049-15.266-27.874 29.28 6.563 53.793 12.965 78.679 17.143 8.693 1.459 18.716-1.368 27.408-4.348 15.339-5.259 24.545-15.794 23.865-33.383-0.664-17.149-11.304-25.157-25.972-28.854-19.636-4.949-39.941-7.543-59.224-13.52-30.839-9.56-46.717-35.762-37.202-65.543 4.324-13.535 17.918-24.109 28.99-36.732z"],"attrs":[{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 37, 4)"},{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 252, 252)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(252, 250, 250)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(250, 248, 248)"},{"fill":"rgb(6, 6, 6)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(12, 12, 12)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(250, 238, 238)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(12, 12, 12)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_low"]},"attrs":[{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 37, 4)"},{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 252, 252)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(252, 250, 250)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(250, 248, 248)"},{"fill":"rgb(6, 6, 6)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(12, 12, 12)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(250, 238, 238)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(12, 12, 12)"}],"properties":{"order":2,"id":2,"name":"gps_signal_low","prevSize":32,"code":59648,"codes":[59648,59649,59650,59651,59652,59653,59654,59655,59656,59657,59658,59659,59660,59661,59662,59663,59664,59665,59666]},"setIdx":0,"setId":0,"iconIdx":0},{"icon":{"paths":["M601.248 1028.697c-200.416 0-398.483 0-596.55 0-0-341.333-0-682.667-0-1024 356.991-0 713.982-0 1070.972-0 0 341.333 0 682.666 0 1024-157.358 0-314.716 0-474.422 0zM992.795 670.585c26.319-76.179 33.921-154.172 18.963-233.408-47.787-253.137-266.071-416.098-522.563-391.022-277.053 27.086-471.494 299.456-412.78 571.963 40.134 186.274 229.787 382.491 455.627 363.915 38.042-3.129 77.887 4.194 114.39-4.212 168.807-38.872 283.272-142.1 346.364-307.236z","M992.239 672.346c-62.537 163.374-177.001 266.603-345.809 305.475-36.502 8.406-76.348 1.083-114.39 4.212-225.84 18.576-415.492-177.641-455.627-363.915-58.714-272.507 135.727-544.877 412.78-571.963 256.493-25.076 474.776 137.885 522.563 391.022 14.958 79.236 7.356 157.229-19.519 235.17zM664.661 812.673c34.442-0.014 68.894 0.519 103.322-0.157 68.659-1.348 123.080-55.748 124.381-124.386 0.682-35.994 0.692-72.023-0.003-108.016-1.326-68.636-55.819-123.928-124.405-124.27-148.722-0.741-297.452-0.743-446.174 0.001-68.563 0.343-123.086 55.742-124.408 124.298-0.634 32.864-0.22 65.75-0.12 98.626 0.245 80.241 53.727 133.784 133.948 133.873 109.587 0.121 219.175 0.031 333.459 0.031zM682.018 249.234c-58.826-19.859-118.173-30.421-180.832-19.534-68.359 11.877-127.277 40.675-177.552 87.976-10.499 9.878-22.386 19.995-6.634 34.441 13.496 12.377 25.599 7.537 37.361-4.155 89.111-88.585 230.179-104.762 339.503-45.382 25.276 13.729 47.029 33.919 70.515 50.983 10.067 7.314 20.821 8.483 29.222-1.699 8.968-10.869 5.112-20.28-4.318-30.329-29.478-31.414-65.62-52.506-107.267-72.301zM643.5 331.137c-28.682-7.041-57.115-18.587-86.096-20.186-60.451-3.335-115.995 13.125-163.652 53.267-26.11 21.993-34.912 35.592-22.149 46.667 22.561 19.577 33.74-3.52 47.501-15.060 37.726-31.635 82.827-48.181 130.31-46.809 53.545 1.548 101.016 25.184 141.615 61.611 5.127 4.6 16.988 1.697 25.729 2.27 0.367-10.311 5.19-25.976 0.338-30.014-22.038-18.339-46.802-33.401-73.596-51.747z","M662.312 812.673c-111.936-0-221.523 0.091-331.111-0.031-80.221-0.089-133.702-53.632-133.948-133.873-0.1-32.876-0.514-65.762 0.12-98.626 1.322-68.556 55.846-123.955 124.408-124.298 148.722-0.745 297.452-0.743 446.174-0.001 68.586 0.342 123.079 55.634 124.405 124.27 0.695 35.994 0.685 72.022 0.003 108.016-1.301 68.638-55.722 123.038-124.381 124.386-34.428 0.676-68.881 0.143-105.671 0.157zM368.775 793.819c130.586-0.001 261.173 0.164 391.759-0.071 67.376-0.121 112.735-45.978 113.104-113.691 0.179-32.841 0.547-65.694-0.096-98.524-1.159-59.195-46.848-106.465-105.64-106.775-148.567-0.785-297.144-0.749-445.711-0.025-57.945 0.282-104.202 46.517-105.834 104.128-1.040 36.722-0.916 73.515-0.024 110.244 1.173 48.284 33.133 89.407 80.327 100.115 21.711 4.926 44.915 3.271 72.114 4.599z","M683.667 250.093c39.997 18.936 76.139 40.028 105.617 71.442 9.43 10.049 13.285 19.46 4.318 30.329-8.401 10.182-19.155 9.012-29.222 1.699-23.486-17.063-45.239-37.254-70.515-50.983-109.325-59.38-250.392-43.203-339.503 45.382-11.762 11.692-23.865 16.532-37.361 4.155-15.752-14.446-3.865-24.563 6.634-34.441 50.274-47.301 109.193-76.099 177.552-87.976 62.658-10.887 122.006-0.326 182.481 20.393z","M645.005 332.189c25.288 17.293 50.053 32.356 72.090 50.695 4.853 4.038 0.030 19.703-0.338 30.014-8.741-0.573-20.601 2.331-25.729-2.27-40.6-36.427-88.071-60.063-141.615-61.611-47.484-1.373-92.584 15.174-130.31 46.809-13.761 11.54-24.94 34.636-47.501 15.060-12.763-11.075-3.961-24.674 22.149-46.667 47.658-40.143 103.201-56.602 163.652-53.267 28.982 1.599 57.415 13.145 87.602 21.238z","M366.439 793.819c-24.863-1.329-48.067 0.327-69.778-4.599-47.194-10.708-79.155-51.831-80.327-100.115-0.892-36.73-1.016-73.522 0.024-110.244 1.632-57.611 47.889-103.846 105.834-104.128 148.568-0.724 297.144-0.76 445.711 0.025 58.792 0.31 104.481 47.581 105.64 106.775 0.642 32.83 0.275 65.683 0.096 98.524-0.369 67.713-45.728 113.57-113.104 113.691-130.586 0.235-261.173 0.070-394.095 0.071zM410.844 657.647c6.827 0.309 13.654 0.619 22.056 1 0 14.41 0.614 27.571-0.338 40.618-0.327 4.485-3.472 10.549-7.185 12.728-40.471 23.743-102.254 0.921-113.308-44.194-5.174-21.115-4.564-45.116-0.526-66.677 6.082-32.478 33.028-52.991 66.314-50.82 26.181 1.708 51.959 9.592 78.275 14.804 5.308-16.108-3.216-24.293-20.19-29.897-58.040-19.164-113.328-6.091-138.535 34.017-26.323 41.883-21.286 111.849 11.512 144.489 36.008 35.836 89.26 35.018 139.289 12.143 3.876-1.772 8.115-7.772 8.234-11.92 0.748-26.179 0.379-52.389 0.379-78.263-27.606 0-52.162 0-77.875 0 0.878 8.232 1.576 14.768 2.345 21.973 9.523 0 17.283 0 29.554 0zM657.369 573.207c-1.997 41.811 9.834 57.724 50.995 67.96 17.323 4.308 35.697 5.977 51.802 12.971 8.886 3.859 18.649 15.769 19.638 24.952 1.019 9.461-5.876 22.55-13.498 29.368-7.288 6.519-20.319 10.495-30.202 9.485-26.452-2.705-52.568-8.684-81.127-13.773 1.527 5.9 0.893 18.391 6.62 23.030 27.401 22.194 96.867 19.471 124.106-3.414 16.705-14.035 24.667-31.973 20.79-54.121-3.782-21.604-17.421-34.603-37.705-40.392-17.18-4.903-34.768-8.413-52.239-12.252-20.136-4.424-36.857-13.551-34.112-36.974 2.673-22.812 21.442-31.392 41.201-29.732 24.914 2.094 49.415 9.105 74.859 14.146 5.42-15.393 0.070-27.113-21.212-30.435-11.497-1.795-22.617-6.101-34.125-7.704-38.083-5.303-68.182 10.241-85.791 46.885zM621.648 561.187c-33.585-44.783-81.323-26.053-124.295-30.444 0 70.19 0 137.675 0 205.577 8.016 0 14.624 0 23.448 0 0-24.832 0-48.61 0-72.033 97.387-10.277 124.705-37.339 100.847-103.1z","M408.589 657.647c-10.016 0-17.776 0-27.299 0-0.769-7.204-1.466-13.74-2.345-21.973 25.713 0 50.269 0 77.875 0 0 25.874 0.369 52.085-0.379 78.263-0.118 4.148-4.358 10.148-8.234 11.92-50.029 22.875-103.28 23.693-139.289-12.143-32.798-32.641-37.836-102.606-11.512-144.489 25.207-40.108 80.495-53.181 138.535-34.017 16.974 5.605 25.498 13.789 20.19 29.897-26.315-5.212-52.093-13.096-78.275-14.804-33.286-2.171-60.232 18.342-66.314 50.82-4.038 21.56-4.648 45.561 0.526 66.677 11.054 45.115 72.837 67.938 113.308 44.194 3.714-2.179 6.858-8.243 7.185-12.728 0.952-13.047 0.338-26.208 0.338-40.618-8.402-0.381-15.229-0.69-24.311-1z","M657.702 571.307c17.275-34.745 47.374-50.289 85.457-44.986 11.509 1.603 22.628 5.909 34.125 7.704 21.282 3.322 26.632 15.042 21.212 30.435-25.444-5.041-49.944-12.052-74.859-14.146-19.759-1.66-38.528 6.92-41.201 29.732-2.745 23.423 13.976 32.549 34.112 36.974 17.471 3.839 35.059 7.348 52.239 12.252 20.284 5.789 33.923 18.788 37.705 40.392 3.877 22.148-4.085 40.086-20.79 54.121-27.239 22.885-96.705 25.608-124.106 3.414-5.727-4.639-5.093-17.13-6.62-23.030 28.558 5.089 54.675 11.068 81.127 13.773 9.883 1.011 22.914-2.966 30.202-9.485 7.622-6.818 14.516-19.906 13.498-29.368-0.989-9.183-10.752-21.093-19.638-24.952-16.105-6.994-34.478-8.663-51.802-12.971-41.16-10.236-52.992-26.149-50.661-69.859z","M622.778 562.655c22.728 64.292-4.59 91.354-101.976 101.631 0 23.423 0 47.201 0 72.033-8.824 0-15.432 0-23.448 0 0-67.902 0-135.386 0-205.577 42.971 4.391 90.71-14.339 125.424 31.912zM604.49 587.095c-12.204-31.237-39.004-40.681-82.929-29.447 0 26.401 0 52.698 0 78.832 58.152 8.154 79.432-3.716 82.929-49.386z","M604.637 588.908c-3.644 43.857-24.924 55.727-83.076 47.573 0-26.134 0-52.432 0-78.832 43.925-11.234 70.725-1.79 83.076 31.26z"],"attrs":[{"fill":"rgb(255, 255, 254)"},{"fill":"rgb(255, 255, 1)"},{"fill":"rgb(6, 6, 0)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(251, 251, 0)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(13, 13, 4)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(251, 251, 0)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_middle"]},"attrs":[{"fill":"rgb(255, 255, 254)"},{"fill":"rgb(255, 255, 1)"},{"fill":"rgb(6, 6, 0)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(251, 251, 0)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(13, 13, 4)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(251, 251, 0)"}],"properties":{"order":3,"id":1,"name":"gps_signal_middle","prevSize":32,"code":59667,"codes":[59667,59668,59669,59670,59671,59672,59673,59674,59675,59676]},"setIdx":0,"setId":0,"iconIdx":1},{"icon":{"paths":["M634.128 1028.697c-211.376 0-420.404 0-629.431 0-0-341.333-0-682.667-0-1024 356.991-0 713.982-0 1070.972-0 0 341.333 0 682.666 0 1024-146.398 0-292.795 0-441.541 0zM1018.959 501.469c-2.949-21.188-6.17-42.343-8.797-63.572-7.842-63.369-29.651-122.3-64.221-175.103-52.965-80.9-122.179-144.268-212.401-183.329-93.652-40.546-190.908-50.996-289.73-30.777-107.563 22.007-197.921 76.162-268.048 162.18-91.023 111.65-127.203 239.557-104.177 380.846 18.831 115.543 74.43 213.335 166.396 288.16 104.879 85.331 223.578 123.823 359.421 107.232 127.561-15.579 230.911-75.57 312.898-171.565 75.519-88.421 105.49-194.946 108.657-314.073z","M1019.106 503.618c-3.315 116.979-33.286 223.503-108.805 311.924-81.987 95.995-185.338 155.986-312.898 171.565-135.842 16.591-254.542-21.901-359.421-107.232-91.966-74.825-147.566-172.617-166.396-288.16-23.027-141.289 13.153-269.197 104.177-380.846 70.127-86.018 160.485-140.173 268.048-162.18 98.822-20.219 196.077-9.769 289.73 30.777 90.221 39.061 159.436 102.428 212.401 183.329 34.569 52.803 56.378 111.734 64.221 175.103 2.627 21.228 5.847 42.383 8.944 65.72zM799.743 807.979c62.703-22.243 92.613-64.375 92.766-130.838 0.074-32.063 0.444-64.135-0.102-96.189-1.189-69.756-55.905-124.893-125.817-125.173-147.803-0.59-295.611-0.59-443.413-0-69.904 0.279-124.673 55.467-125.831 125.172-0.533 32.055-0.164 64.126-0.096 96.189 0.174 82.015 53.086 135.436 134.513 135.5 141.549 0.11 283.097 0.132 424.645-0.139 13.163-0.025 26.322-2.415 43.334-4.522zM845.943 290.783c19.664-10.476 16.044-24.67 4.691-38.181-6.827-8.124-16.424-13.898-24.667-20.858-102.658-86.687-220.311-118.998-352.495-95.284-83.844 15.042-156.91 52.061-217.902 112.387-11.64 11.513-17.353 25.465-7.901 36.833 10.802 12.99 25.375 4.53 36.919-4.494 1.834-1.434 3.342-3.283 5.018-4.923 60.514-59.235 134.53-92.844 217.163-101.47 109.754-11.457 209.174 18.078 293.803 91.941 11.899 10.386 27.653 16.356 45.371 24.049zM775.039 307.636c-78.335-64.668-166.752-92.678-268.706-78.131-71.31 10.174-131.594 40.482-183.638 89.055-10.127 9.451-20.415 19.409-6.217 33.024 13.592 13.034 25.731 7.147 37.973-3.565 13.894-12.158 27.903-24.545 43.376-34.475 61.476-39.454 128.107-52.37 200.921-41.953 56.244 8.047 104.338 30.4 146.366 67.287 13.962 12.254 29.686 30.189 46.735 14.515 19.369-17.807-2.919-30.777-16.81-45.756zM399.999 413.2c4.109-3.525 8.218-7.050 12.327-10.576 55.468-47.602 118.517-67.82 188.788-42.195 32.254 11.762 60.401 34.606 90.859 51.624 5.929 3.313 16.294 6.3 20.4 3.423 5.732-4.015 9.759-13.546 10.223-20.983 0.345-5.545-4.97-12.755-9.708-17.108-71.283-65.488-154.002-84.582-245.127-52.948-31.757 11.024-60.431 32.244-88.491 51.721-7.438 5.163-7.376 21.133-10.757 32.141 9.337 1.91 18.674 3.821 31.487 4.902z","M797.817 808.386c-15.087 1.699-28.245 4.090-41.408 4.115-141.548 0.271-283.097 0.249-424.645 0.139-81.427-0.063-134.339-53.485-134.513-135.5-0.068-32.063-0.437-64.134 0.096-96.189 1.159-69.705 55.927-124.893 125.831-125.172 147.803-0.59 295.611-0.59 443.413 0 69.912 0.279 124.629 55.417 125.817 125.173 0.546 32.054 0.176 64.126 0.102 96.189-0.153 66.463-30.063 108.596-94.692 131.246zM462.679 793.82c100.986-0.005 201.975 0.427 302.958-0.18 60.49-0.363 106.842-46.898 107.908-107.238 0.608-34.434 0.52-68.894 0.025-103.332-0.887-61.658-47.25-108.284-109.092-108.475-146.39-0.453-292.783-0.452-439.173-0.001-61.838 0.191-108.207 46.807-109.117 108.458-0.496 33.655-0.422 67.327-0.021 100.984 0.751 63.060 47.040 109.14 110.297 109.701 43.836 0.389 87.678 0.079 136.214 0.082z","M844.068 290.944c-15.844-7.853-31.597-13.823-43.497-24.209-84.628-73.863-184.049-103.398-293.803-91.941-82.633 8.626-156.65 42.235-217.163 101.47-1.675 1.64-3.184 3.489-5.018 4.923-11.544 9.024-26.117 17.485-36.919 4.494-9.453-11.368-3.739-25.32 7.901-36.833 60.992-60.327 134.058-97.345 217.902-112.387 132.184-23.715 249.838 8.597 352.495 95.284 8.242 6.96 17.84 12.734 24.667 20.858 11.353 13.51 14.973 27.705-6.565 38.341z","M776.248 308.845c12.682 13.769 34.97 26.74 15.6 44.547-17.049 15.674-32.774-2.26-46.735-14.515-42.028-36.887-90.122-59.24-146.366-67.287-72.815-10.418-139.446 2.499-200.921 41.953-15.472 9.93-29.482 22.317-43.376 34.475-12.242 10.712-24.38 16.599-37.973 3.565-14.197-13.615-3.909-23.572 6.217-33.024 52.044-48.573 112.328-78.88 183.638-89.055 101.954-14.546 190.371 13.463 269.916 79.34z","M398.261 413.615c-11.075-1.496-20.412-3.406-29.749-5.317 3.381-11.008 3.319-26.978 10.757-32.141 28.060-19.476 56.734-40.696 88.491-51.721 91.125-31.634 173.844-12.54 245.127 52.948 4.738 4.353 10.054 11.563 9.708 17.108-0.463 7.438-4.491 16.968-10.223 20.983-4.106 2.876-14.471-0.111-20.4-3.423-30.457-17.017-58.605-39.862-90.859-51.624-70.271-25.626-133.319-5.407-188.788 42.195-4.109 3.526-8.218 7.051-14.065 10.991z","M460.33 793.82c-46.188-0.003-90.030 0.307-133.865-0.082-63.258-0.561-109.546-46.641-110.297-109.701-0.401-33.657-0.475-67.329 0.021-100.984 0.909-61.651 47.278-108.267 109.117-108.458 146.39-0.451 292.783-0.452 439.173 0.001 61.841 0.191 108.205 46.817 109.092 108.475 0.495 34.438 0.584 68.898-0.025 103.332-1.066 60.34-47.418 106.875-107.908 107.238-100.983 0.607-201.972 0.174-305.307 0.18zM340.633 734.174c35.799 14.349 70.394 7.23 104.144-6.899 5.113-2.141 11.149-9.453 11.386-14.62 1.171-25.462 0.532-51.008 0.532-76.842-27.198 0-51.657 0-75.875 0 0 7.697 0 13.674 0 22.485 17.769 0 34.459 0 52.007 0 0 14.544 1.262 26.438-0.504 37.863-0.961 6.217-5.759 14.609-11.061 16.943-38.518 16.957-84.093 3.123-102.989-30.044-21.968-38.559-13.994-97.141 18.296-119.752 10.837-7.589 26.101-13.677 38.802-12.783 26.576 1.871 52.794 8.84 80.39 13.943 4.744-12.517 0.763-23.549-16.791-27.935-10.55-2.636-21.136-5.176-31.792-7.328-55.339-11.175-102.859 12.441-119.261 60.624-15.491 45.51-9.434 119.357 52.716 144.345zM661.318 562.453c-12.57 40.998 1.507 66.808 42.796 77.559 18.777 4.889 38.636 6.857 56.313 14.213 8.794 3.66 18.328 16.050 19.211 25.287 0.905 9.46-6.123 22.435-13.802 29.166-7.362 6.452-20.389 10.329-30.272 9.265-26.437-2.848-52.522-8.954-81.688-14.305 2.368 7.142 2.569 19.328 8.532 23.757 27.572 20.48 90.308 19.552 118.496-0.039 18.721-13.012 28.751-30.903 26.118-54.048-2.676-23.529-16.679-38.243-39.23-44.283-19.539-5.233-39.435-9.122-59.019-14.2-15.932-4.132-26.398-14.267-26.752-31.326-0.367-17.68 11.667-26.503 26.824-31.211 6.559-2.037 14.138-3.582 20.689-2.35 22.963 4.317 45.681 9.94 71.626 15.771-2.892-8.827-3.314-22.748-8.993-25.396-36.951-17.233-99.421-26.774-130.849 22.141zM623.879 624.249c14.226-41.402 3.962-76.291-30.808-85.39-30.58-8.002-63.426-7.345-95.358-10.52 0 73.371 0 140.308 0 207.64 8.016 0 14.555 0 23.827 0 0-25.128 0-48.859 0-72.994 39.077-1.297 77.422 2.354 102.339-38.736z","M338.867 733.605c-60.385-24.419-66.442-98.266-50.95-143.776 16.401-48.183 63.922-71.799 119.261-60.624 10.657 2.152 21.243 4.692 31.792 7.328 17.554 4.386 21.535 15.418 16.791 27.935-27.596-5.103-53.814-12.071-80.39-13.943-12.701-0.894-27.964 5.194-38.802 12.783-32.29 22.611-40.264 81.194-18.296 119.752 18.897 33.168 64.471 47.001 102.989 30.044 5.302-2.334 10.1-10.726 11.061-16.943 1.766-11.425 0.504-23.319 0.504-37.863-17.548 0-34.239 0-52.007 0 0-8.811 0-14.788 0-22.485 24.218 0 48.676 0 75.875 0 0 25.834 0.639 51.38-0.532 76.842-0.238 5.167-6.273 12.479-11.386 14.62-33.75 14.129-68.344 21.248-105.909 6.329z","M662.091 560.759c30.656-47.221 93.125-37.68 130.076-20.448 5.679 2.648 6.101 16.569 8.993 25.396-25.945-5.831-48.663-11.454-71.626-15.771-6.551-1.232-14.13 0.312-20.689 2.35-15.157 4.708-27.191 13.531-26.824 31.211 0.354 17.060 10.82 27.195 26.752 31.326 19.584 5.079 39.48 8.967 59.019 14.2 22.551 6.040 36.554 20.754 39.23 44.283 2.633 23.145-7.397 41.036-26.118 54.048-28.188 19.592-90.924 20.519-118.496 0.039-5.963-4.429-6.164-16.614-8.532-23.757 29.166 5.351 55.252 11.457 81.688 14.305 9.883 1.065 22.911-2.812 30.272-9.265 7.68-6.731 14.707-19.706 13.802-29.166-0.883-9.236-10.418-21.627-19.211-25.287-17.677-7.356-37.536-9.324-56.313-14.213-41.289-10.751-55.366-36.561-42.024-79.253z","M622.875 625.792c-23.913 39.547-62.258 35.895-101.335 37.193 0 24.135 0 47.866 0 72.994-9.272 0-15.811 0-23.827 0 0-67.332 0-134.269 0-207.64 31.933 3.176 64.779 2.518 95.358 10.52 34.77 9.099 45.034 43.987 29.804 86.933zM571.737 555.427c-16.744 0-33.488 0-49.651 0 0 28.983 0 55.24 0 81.277 50.406 6.214 72.301-1.84 80.559-28.949 7.077-23.233-1.362-39.302-30.908-52.328z","M573.663 555.832c27.62 12.621 36.059 28.689 28.982 51.922-8.258 27.108-30.152 35.162-80.559 28.949 0-26.037 0-52.294 0-81.277 16.163 0 32.907 0 51.576 0.406z"],"attrs":[{"fill":"rgb(254, 255, 255)"},{"fill":"rgb(70, 248, 5)"},{"fill":"rgb(2, 5, 0)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(69, 244, 5)"},{"fill":"rgb(6, 11, 4)"},{"fill":"rgb(6, 12, 4)"},{"fill":"rgb(5, 11, 4)"},{"fill":"rgb(69, 244, 5)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_high"]},"attrs":[{"fill":"rgb(254, 255, 255)"},{"fill":"rgb(70, 248, 5)"},{"fill":"rgb(2, 5, 0)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(69, 244, 5)"},{"fill":"rgb(6, 11, 4)"},{"fill":"rgb(6, 12, 4)"},{"fill":"rgb(5, 11, 4)"},{"fill":"rgb(69, 244, 5)"}],"properties":{"order":4,"id":0,"name":"gps_signal_high","prevSize":32,"code":59677,"codes":[59677,59678,59679,59680,59681,59682,59683,59684,59685,59686,59687]},"setIdx":0,"setId":0,"iconIdx":2}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showCodes":true,"showQuickUse":true,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon"},"metrics":{"emSize":1024,"baseline":6.25,"whitespace":50},"embed":false},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215},"historySize":50}} \ No newline at end of file diff --git a/assets/customIcon/icomoon/style.css b/assets/customIcon/icomoon/style.css new file mode 100644 index 0000000..181312b --- /dev/null +++ b/assets/customIcon/icomoon/style.css @@ -0,0 +1,224 @@ +@font-face { + font-family: 'icomoon'; + src: url('fonts/icomoon.eot?eq8f84'); + src: url('fonts/icomoon.eot?eq8f84#iefix') format('embedded-opentype'), + url('fonts/icomoon.ttf?eq8f84') format('truetype'), + url('fonts/icomoon.woff?eq8f84') format('woff'), + url('fonts/icomoon.svg?eq8f84#icomoon') format('svg'); + font-weight: normal; + font-style: normal; + font-display: block; +} + +[class^="icon-"], [class*=" icon-"] { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'icomoon' !important; + speak: never; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-gps_signal_low .path1:before { + content: "\e900"; + color: rgb(255, 253, 253); +} +.icon-gps_signal_low .path2:before { + content: "\e901"; + margin-left: -1.0458984375em; + color: rgb(255, 37, 4); +} +.icon-gps_signal_low .path3:before { + content: "\e902"; + margin-left: -1.0458984375em; + color: rgb(255, 253, 253); +} +.icon-gps_signal_low .path4:before { + content: "\e903"; + margin-left: -1.0458984375em; + color: rgb(255, 252, 252); +} +.icon-gps_signal_low .path5:before { + content: "\e904"; + margin-left: -1.0458984375em; + color: rgb(251, 251, 251); +} +.icon-gps_signal_low .path6:before { + content: "\e905"; + margin-left: -1.0458984375em; + color: rgb(252, 250, 250); +} +.icon-gps_signal_low .path7:before { + content: "\e906"; + margin-left: -1.0458984375em; + color: rgb(5, 5, 5); +} +.icon-gps_signal_low .path8:before { + content: "\e907"; + margin-left: -1.0458984375em; + color: rgb(1, 1, 1); +} +.icon-gps_signal_low .path9:before { + content: "\e908"; + margin-left: -1.0458984375em; + color: rgb(250, 248, 248); +} +.icon-gps_signal_low .path10:before { + content: "\e909"; + margin-left: -1.0458984375em; + color: rgb(6, 6, 6); +} +.icon-gps_signal_low .path11:before { + content: "\e90a"; + margin-left: -1.0458984375em; + color: rgb(10, 10, 10); +} +.icon-gps_signal_low .path12:before { + content: "\e90b"; + margin-left: -1.0458984375em; + color: rgb(12, 12, 12); +} +.icon-gps_signal_low .path13:before { + content: "\e90c"; + margin-left: -1.0458984375em; + color: rgb(251, 251, 251); +} +.icon-gps_signal_low .path14:before { + content: "\e90d"; + margin-left: -1.0458984375em; + color: rgb(10, 10, 10); +} +.icon-gps_signal_low .path15:before { + content: "\e90e"; + margin-left: -1.0458984375em; + color: rgb(250, 238, 238); +} +.icon-gps_signal_low .path16:before { + content: "\e90f"; + margin-left: -1.0458984375em; + color: rgb(1, 1, 1); +} +.icon-gps_signal_low .path17:before { + content: "\e910"; + margin-left: -1.0458984375em; + color: rgb(113, 106, 106); +} +.icon-gps_signal_low .path18:before { + content: "\e911"; + margin-left: -1.0458984375em; + color: rgb(113, 106, 106); +} +.icon-gps_signal_low .path19:before { + content: "\e912"; + margin-left: -1.0458984375em; + color: rgb(12, 12, 12); +} +.icon-gps_signal_middle .path1:before { + content: "\e913"; + color: rgb(255, 255, 254); +} +.icon-gps_signal_middle .path2:before { + content: "\e914"; + margin-left: -1.0458984375em; + color: rgb(255, 255, 1); +} +.icon-gps_signal_middle .path3:before { + content: "\e915"; + margin-left: -1.0458984375em; + color: rgb(6, 6, 0); +} +.icon-gps_signal_middle .path4:before { + content: "\e916"; + margin-left: -1.0458984375em; + color: rgb(2, 2, 2); +} +.icon-gps_signal_middle .path5:before { + content: "\e917"; + margin-left: -1.0458984375em; + color: rgb(1, 1, 1); +} +.icon-gps_signal_middle .path6:before { + content: "\e918"; + margin-left: -1.0458984375em; + color: rgb(251, 251, 0); +} +.icon-gps_signal_middle .path7:before { + content: "\e919"; + margin-left: -1.0458984375em; + color: rgb(11, 11, 4); +} +.icon-gps_signal_middle .path8:before { + content: "\e91a"; + margin-left: -1.0458984375em; + color: rgb(13, 13, 4); +} +.icon-gps_signal_middle .path9:before { + content: "\e91b"; + margin-left: -1.0458984375em; + color: rgb(11, 11, 4); +} +.icon-gps_signal_middle .path10:before { + content: "\e91c"; + margin-left: -1.0458984375em; + color: rgb(251, 251, 0); +} +.icon-gps_signal_high .path1:before { + content: "\e91d"; + color: rgb(254, 255, 255); +} +.icon-gps_signal_high .path2:before { + content: "\e91e"; + margin-left: -1.0458984375em; + color: rgb(70, 248, 5); +} +.icon-gps_signal_high .path3:before { + content: "\e91f"; + margin-left: -1.0458984375em; + color: rgb(2, 5, 0); +} +.icon-gps_signal_high .path4:before { + content: "\e920"; + margin-left: -1.0458984375em; + color: rgb(1, 1, 1); +} +.icon-gps_signal_high .path5:before { + content: "\e921"; + margin-left: -1.0458984375em; + color: rgb(2, 2, 2); +} +.icon-gps_signal_high .path6:before { + content: "\e922"; + margin-left: -1.0458984375em; + color: rgb(1, 1, 1); +} +.icon-gps_signal_high .path7:before { + content: "\e923"; + margin-left: -1.0458984375em; + color: rgb(69, 244, 5); +} +.icon-gps_signal_high .path8:before { + content: "\e924"; + margin-left: -1.0458984375em; + color: rgb(6, 11, 4); +} +.icon-gps_signal_high .path9:before { + content: "\e925"; + margin-left: -1.0458984375em; + color: rgb(6, 12, 4); +} +.icon-gps_signal_high .path10:before { + content: "\e926"; + margin-left: -1.0458984375em; + color: rgb(5, 11, 4); +} +.icon-gps_signal_high .path11:before { + content: "\e927"; + margin-left: -1.0458984375em; + color: rgb(69, 244, 5); +} diff --git a/assets/fonts/icomoon.ttf b/assets/fonts/icomoon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f2e8bb498da09a4406f059d856e8888f7e7c72bd GIT binary patch literal 8164 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 b#kEJkPYc3&puovc0mvBqpLDNNezE;O{)`jr literal 0 HcmV?d00001 diff --git a/lib/data/location_data.dart b/lib/data/location_data.dart index 608819d..a7e8d6f 100644 --- a/lib/data/location_data.dart +++ b/lib/data/location_data.dart @@ -1,4 +1,5 @@ // ignore: non_constant_identifier_names +// 不要 String location_line_date = """ { "type": "FeatureCollection", diff --git a/lib/main.dart b/lib/main.dart index 51ceaae..e6e50da 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,12 @@ +import 'dart:async'; +//import 'dart:convert'; +//import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart'; import 'package:get/get.dart'; +//import 'package:vm_service/vm_service.dart'; +//import 'package:dart_vm_info/dart_vm_info.dart'; + import 'package:rogapp/pages/destination/destination_controller.dart'; import 'package:rogapp/pages/index/index_binding.dart'; import 'package:rogapp/routes/app_pages.dart'; @@ -66,6 +72,8 @@ void main() async { ErrorService.reportError(details.exception, details.stack ?? StackTrace.current, deviceInfo); }; + // startMemoryMonitoring(); // 2024-4-8 Akira: メモリ使用量のチェックを開始 See #2810 + runZonedGuarded(() { runApp(const ProviderScope(child: MyApp())); }, (error, stackTrace) { @@ -75,6 +83,72 @@ void main() async { //runApp(const MyApp()); } +// メモリ使用量の解説:https://qiita.com/hukusuke1007/items/e4e987836412e9bc73b9 + +/* +// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810 +// startMemoryMonitoring関数が5分ごとに呼び出され、メモリ使用量をチェックします。 +// メモリ使用量が閾値(ここでは500MB)を超えた場合、エラーメッセージとスタックトレースをレポートします。 +// +void startMemoryMonitoring() { + const threshold = 500 * 1024 * 1024; // 500MB + + // メモリ使用量情報を取得 + final memoryUsage = MemoryUsage.fromJson(DartVMInfo.getAllocationProfile()); + + if (memoryUsage.heapUsage > threshold) { + final now = DateTime.now().toIso8601String(); + final message = 'High memory usage detected at $now: ${memoryUsage.heapUsage} bytes'; + print(message); + reportError(message, StackTrace.current); + showMemoryWarningDialog(); + } + + Timer(const Duration(minutes: 5), startMemoryMonitoring); +} + +class MemoryUsage { + final int heapUsage; + + MemoryUsage({required this.heapUsage}); + + factory MemoryUsage.fromJson(Map json) { + return MemoryUsage( + heapUsage: json['heapUsage'] as int, + ); + } +} +*/ + +// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810 +// reportError関数でエラーレポートを送信します。具体的な実装は、利用するエラー報告サービスによって異なります。 +void reportError(String message, StackTrace stackTrace) async { + // エラーレポートの送信処理を実装 + // 例: SentryやFirebase Crashlyticsなどのエラー報告サービスを利用 + print("ReportError : ${message} . stacktrace : ${stackTrace}"); +} + +// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810 +// showMemoryWarningDialog関数で、メモリ使用量が高い場合にユーザーに警告ダイアログを表示します。 +// +void showMemoryWarningDialog() { + if (Get.context != null) { + showDialog( + context: Get.context!, + builder: (context) => AlertDialog( + title: const Text('メモリ使用量の警告'), + content: const Text('アプリのメモリ使用量が高くなっています。アプリを再起動することをお勧めします。'), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('OK'), + ), + ], + ), + ); + } +} + class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); diff --git a/lib/model/auth_user.dart b/lib/model/auth_user.dart index bd71551..c77922e 100644 --- a/lib/model/auth_user.dart +++ b/lib/model/auth_user.dart @@ -1,3 +1,6 @@ +// プロパティの型がString?やint?などのオプショナル型になっています。 +// これらのプロパティが常に値を持つことが保証されている場合は、非オプショナル型を使用することで、不要なnullチェックを回避できます。 +// class AuthUser { AuthUser(); diff --git a/lib/model/destination.dart b/lib/model/destination.dart index 951f55e..89e2147 100644 --- a/lib/model/destination.dart +++ b/lib/model/destination.dart @@ -1,3 +1,6 @@ +// プロパティの型がString?やint?などのオプショナル型になっています。 +// これらのプロパティが常に値を持つことが保証されている場合は、非オプショナル型を使用することで、不要なnullチェックを回避できます。 +// class Destination { String? name; String? address; diff --git a/lib/pages/camera/camera_page.dart b/lib/pages/camera/camera_page.dart index 3558781..8e015b5 100644 --- a/lib/pages/camera/camera_page.dart +++ b/lib/pages/camera/camera_page.dart @@ -31,6 +31,8 @@ String getTagText(bool isRecept, String? tags) { return ""; } +// 要修正:画像の読み込みエラーが発生した場合のエラーハンドリングが不十分です。エラーメッセージを表示するなどの処理を追加してください。 +// Image getDisplayImage(Destination destination) { String serverUrl = ConstValues.currentServer(); @@ -104,6 +106,8 @@ class CameraPage extends StatelessWidget { Timer? timer; + // 要修正:エラーハンドリングが不十分です。例外が発生した場合の処理を追加することをお勧めします。 + // Widget getAction(BuildContext context) { //print("----cccheckin is --- ${dbDest?.checkedin} ----"); if (manulaCheckin == true) { @@ -431,6 +435,8 @@ class BuyPointCamera extends StatelessWidget { height: 370, decoration: BoxDecoration( image: DecorationImage( + // 要修正:getReceiptImage関数の戻り値がnullの場合のエラーハンドリングが不十分です。適切なデフォルト画像を表示するなどの処理を追加してください。 + // image: getReceiptImage(), fit: BoxFit.cover)), ), ), diff --git a/lib/pages/changepassword/change_password_page_controller.dart b/lib/pages/changepassword/change_password_page_controller.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/pages/destination/destination_controller.dart b/lib/pages/destination/destination_controller.dart index b146bdf..e11d067 100644 --- a/lib/pages/destination/destination_controller.dart +++ b/lib/pages/destination/destination_controller.dart @@ -33,6 +33,8 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; +import 'package:geolocator/geolocator.dart'; + // 目的地に関連する状態管理とロジックを担当するクラスです。 // class DestinationController extends GetxController { @@ -44,6 +46,8 @@ class DestinationController extends GetxController { List destinations = [].obs; // 目的地のリストを保持するObservable変数です。 double currentLat = 0.0; // 現在の緯度と経度を保持する変数です。 double currentLon = 0.0; + double lastValidLat = 0.0; // 最後に中・強信号で拾ったGPS位置。ロゲ開始を屋内でやったら 0 のままなので、屋外で行うこと。 + double lastValidLon = 0.0; DateTime lastGPSCollectedTime = DateTime.now(); // 最後にGPSデータが収集された時刻を保持する変数です。 bool shouldShowBottomSheet = true; // ボトムシートを表示すべきかどうかを示すフラグです。 @@ -75,6 +79,7 @@ class DestinationController extends GetxController { var travelMode = 0.obs; // 移動モードを保持するReactive変数です。 bool skipGps = false; // GPSをスキップするかどうかを示すフラグです。 + bool okToUseGPS = false; // 最新のGPS情報を使用して良いかを示すフラグ。 Map matrix = {}; // 行列データを保持する変数です。 @@ -199,6 +204,10 @@ class DestinationController extends GetxController { // 目的地がデータベースに存在しない場合は、新しい目的地としてデータベースに挿入します。 // 目的地に応じて、チェックイン、ゴール、買い物ポイントの処理を行います。 // + // 2024-4-8 akira: GPS信号が弱い場合でも、最後に取得した位置情報を使用してチェックインやゴールの処理を続行できるようになります。また、チェックインやゴールの処理では、GPS信号の精度チェックを緩和することで、GPS信号が弱い場合でもボタンを押せるようになります。 + // + // 要検討:エラーが発生した場合のエラーハンドリングを追加し、適切なメッセージを表示することを検討してください。 + // Future startTimer(Destination d, double distance) async { //print("=== passed dest is ${d.location_id} ${d.checkedin} ===="); skipGps = true; @@ -240,6 +249,31 @@ class DestinationController extends GetxController { // comment out by Akira, 2024-4-5 // skipGps = false; // return; + // GPS信号が弱い場合、最後に取得した高いまたは中程度の位置情報を使用 + if (okToUseGPS) { + double lastValidDistance = Geolocator.distanceBetween( + lastValidLat, lastValidLon, + d.lat!, d.lon! + ); + /* + double lastValidDistance = distance.as( + LengthUnit.Meter, + LatLng(lastValidLat, lastValidLon), + LatLng(d.lat!, d.lon!), + ); + */ + + if (checkinRadious >= lastValidDistance || checkinRadious == -1) { + indexController.currentDestinationFeature.clear(); + indexController.currentDestinationFeature.add(d); + } else { + skipGps = false; + return; + } + } else { + skipGps = false; + return; + } } if (isPhotoShoot.value == true) { @@ -407,10 +441,10 @@ class DestinationController extends GetxController { context: Get.context!, isScrollControlled: true, builder: ((context) => CameraPage( - buyPointPhoto: true, - destination: d, - dbDest: ds.first, - ))).whenComplete(() { + destination: d, + buyPointPhoto: true, + dbDest: ds.first, + ))).whenComplete(() { shouldShowBottomSheet = true; skipGps = false; rogainingCounted.value = true; @@ -641,13 +675,14 @@ class DestinationController extends GetxController { }); } else { Get.snackbar( - "始まっていません", - "ロゲ開始ボタンをタップして、ロゲイニングを始める必要があります", - icon: const Icon(Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue), - snackPosition: SnackPosition.TOP, - duration: const Duration(seconds: 3), - backgroundColor: Colors.yellow, - ); + "ロゲが始まっていません", + "ロゲ開始ボタンをタップして、ロゲイニングを始める必要があります", + icon: const Icon( + Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue), + snackPosition: SnackPosition.TOP, + duration: const Duration(seconds: 3), + backgroundColor: Colors.yellow, + ); } } } @@ -680,6 +715,9 @@ class DestinationController extends GetxController { // 目的地のリストを走査し、現在位置がチェックイン半径内にある場合は、チェックインの処理を行います。 // GPSデータの送信を開始します。 // + // 2024-4-8 Akira : See 2809 + // checkForCheckinメソッドの再帰呼び出しをunawaitedで囲んで、非同期処理の結果を待たずに先に進むようにしました。また、再帰呼び出しの前に一定時間待機するようにしました。 + // Future checkForCheckin() async { //print("--- Start of checkForCheckin function ---"); dbService.updateDatabase(); @@ -705,15 +743,16 @@ class DestinationController extends GetxController { }); if (gps_push_started == false) { - pushGPStoServer(); + unawaited( pushGPStoServer() ); } //print("--- 123 ---- $skip_gps----"); } catch (e) { - //print("An error occurred: $e"); - await checkForCheckin(); + print("An error occurred: $e"); + // await checkForCheckin(); } finally { + await Future.delayed(const Duration(seconds: 5)); // 一定時間待機してから再帰呼び出し //print("--- End of checkForCheckin function, calling recursively ---"); - await checkForCheckin(); + unawaited( checkForCheckin() ); } } @@ -772,6 +811,8 @@ class DestinationController extends GetxController { // 買い物ポイントを作成する関数です。 指定された目的地に対して買い物ポイントの処理を行います。 // + // 買い物ポイントの作成に失敗した場合のエラーハンドリングを追加することを検討してください。 + // Future makeBuyPoint(Destination destination, String imageurl) async { DatabaseHelper db = DatabaseHelper.instance; await db.updateBuyPoint(destination, imageurl); @@ -804,6 +845,8 @@ class DestinationController extends GetxController { // チェックインを行う関数です。 指定された目的地に対してチェックインの処理を行います。 // + // 要検討:チェックインのリクエストが失敗した場合のエラーハンドリングを追加することをお勧めします。 + // Future makeCheckin( Destination destination, bool action, String imageurl) async { // print("~~~~ calling checkin function ~~~~"); @@ -873,6 +916,9 @@ class DestinationController extends GetxController { @override void onInit() async { super.onInit(); + + // 要検討:エラーメッセージを表示するなどの適切な処理を追加することを検討してください。 + // locationController.locationMarkerPositionStream.listen( (locationMarkerPosition) { if (locationMarkerPosition != null) { @@ -896,9 +942,49 @@ class DestinationController extends GetxController { // 現在位置とスタート地点との距離を計算します。 // 現在位置と前回の位置情報との距離と時間差を確認し、一定の条件を満たす場合はGPSデータをデータベースに追加します。 // + // 要検討:GPSデータの追加に失敗した場合のエラーハンドリングを追加することをお勧めします。 + // void handleLocationUpdate(LocationMarkerPosition? position) async { try { - if (position != null) { + final DestinationController destinationController = Get.find(); + final signalStrength = destinationController.getGpsSignalStrength(); + okToUseGPS = false; + double prevLat = lastValidLat; // 一つ前の位置情報を記録 + double prevLon = lastValidLon; + + if (position!=null && (signalStrength == 'high' || signalStrength == 'medium')) { + // 信号強度が高いまたは中程度の場合、現在の位置情報を更新 + currentLat = position.latitude; + currentLon = position.longitude; + lastValidLat = position.latitude; + lastValidLon = position.longitude; + okToUseGPS = true; + } else { + // 信号強度が低い場合、最後に取得した高いまたは中程度の位置情報を使用 + // 但し、最初から高精度のものがない場合、どうするか? + // + if (lastValidLat != 0.0 && lastValidLon != 0.0) { + currentLat = lastValidLat; + currentLon = lastValidLon; + okToUseGPS = true; + } else { + // GPSの届く場所に行って、信号を拾ってください。とメッセージを出す。 + position = null; + print("GPSの届く場所に行って、信号を拾ってください。"); + Get.snackbar( + "GPS信号を正確に拾えていません", + "空が大きく見えるところへ行ってGPS信号を拾ってください。", + icon: const Icon( + Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue), + snackPosition: SnackPosition.TOP, + duration: const Duration(seconds: 3), + backgroundColor: Colors.yellow, + ); + } + } + + if (okToUseGPS && position!=null) { + // スタート位置から150m離れたら、ready_for_goal if (distanceToStart() >= 150) { ready_for_goal = true; } @@ -907,10 +993,11 @@ class DestinationController extends GetxController { double distanceToDest = distance.as( LengthUnit.Meter, LatLng(position.latitude, position.longitude), - LatLng(currentLat, currentLon)); + LatLng(prevLat, prevLon) + ); - Duration difference = - lastGPSCollectedTime.difference(DateTime.now()).abs(); + Duration difference = lastGPSCollectedTime.difference(DateTime.now()).abs(); + // 最後にGPS信号を取得した時刻から10秒以上経過、かつ10m以上経過(普通に歩くスピード) if (difference.inSeconds >= 10 || distanceToDest >= 10) { // print( // "^^^^^^^^ GPS data collected ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}, ^^^ ${position.latitude}, ${position.longitude}"); @@ -931,10 +1018,10 @@ class DestinationController extends GetxController { currentLon = position.longitude; } */ - if (position != null) { + if (okToUseGPS) { // 位置情報が取得できた場合、精度に関わらず最後の位置情報を更新 - currentLat = position.latitude; - currentLon = position.longitude; + //currentLat = position.latitude; + //currentLon = position.longitude; } } } @@ -1020,25 +1107,32 @@ class DestinationController extends GetxController { if (token != null && token.isNotEmpty) { await indexController.loadUserDetailsForToken(token); fixMapBound(token); - return; + }else { + Get.toNamed(AppPages.LOGIN)!.then((value) { + if (indexController.currentUser.isNotEmpty) { + final tk = indexController.currentUser[0]["token"]; + fixMapBound(tk); + } else { + Get.toNamed(AppPages.TRAVEL); + PerfectureService.getSubExt("9").then((value) { + if (value != null) { + LatLngBounds bnds = LatLngBounds( + LatLng(value[1], value[0]), LatLng(value[3], value[2])); + indexController.mapController + .fitBounds(bnds); //.centerZoomFitBounds(bnds); + } + }); + } + }); } - Get.toNamed(AppPages.LOGIN)!.then((value) { - if (indexController.currentUser.isNotEmpty) { - final tk = indexController.currentUser[0]["token"]; - fixMapBound(tk); - } else { - Get.toNamed(AppPages.TRAVEL); - PerfectureService.getSubExt("9").then((value) { - if (value != null) { - LatLngBounds bnds = LatLngBounds( - LatLng(value[1], value[0]), LatLng(value[3], value[2])); - indexController.mapController - .fitBounds(bnds); //.centerZoomFitBounds(bnds); - } - }); + // 地図のイベントリスナーを設定 + indexController.mapController.mapEventStream.listen((MapEvent mapEvent) { + if (mapEvent is MapEventMoveEnd) { + indexController.loadLocationsBound(); } }); + super.onReady(); } @@ -1106,7 +1200,7 @@ class DestinationController extends GetxController { print("center is ${currentLon}, ${currentLon}"); return true; }()); - // Akira + // Akira ... 状況によって呼ぶか呼ばないか if (currentLat != 0 || currentLon != 0) { indexController.mapController.move(LatLng(currentLat, currentLon), 17.0); } @@ -1236,22 +1330,36 @@ class DestinationController extends GetxController { // 目的地の選択状態を切り替える関数です。 // void toggleSelection(Destination dest) async { - DatabaseHelper db = DatabaseHelper.instance; - await db.toggleSelecttion(dest); - destinations.clear(); - db.getDestinations().then((value) { - destinationCount.value = 0; - currentSelectedDestinations.clear(); - for (Destination d in value) { - //print("------ destination controller populating destination-------- ${d.checkedin}-------- :::::"); - //print("-----populated----- ${d.toMap()}"); - if (d.selected!) { - currentSelectedDestinations.add(d); + try { + DatabaseHelper db = DatabaseHelper.instance; + await db.toggleSelecttion(dest); + destinations.clear(); + db.getDestinations().then((value) { + destinationCount.value = 0; + currentSelectedDestinations.clear(); + for (Destination d in value) { + //print("------ destination controller populating destination-------- ${d.checkedin}-------- :::::"); + //print("-----populated----- ${d.toMap()}"); + if (d.selected!) { + currentSelectedDestinations.add(d); + } + destinations.add(d); } - destinations.add(d); - } - destinationCount.value = destinations.length; - }); + destinationCount.value = destinations.length; + }); + } catch( e ){ + print('Error in toggleSelection: $e'); + Get.snackbar( + "画面切り替えでエラー", + "画面の切り替えができませんでした", + icon: const Icon( + Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue), + snackPosition: SnackPosition.TOP, + duration: const Duration(seconds: 3), + backgroundColor: Colors.yellow, + ); + + } } // ダイアログを表示する関数です。 diff --git a/lib/pages/destination/destination_page.dart b/lib/pages/destination/destination_page.dart deleted file mode 100644 index 7b7928f..0000000 --- a/lib/pages/destination/destination_page.dart +++ /dev/null @@ -1,252 +0,0 @@ -// import 'package:flutter/material.dart'; -// import 'package:geolocator/geolocator.dart'; -// import 'package:get/get.dart'; -// import 'package:latlong2/latlong.dart'; -// import 'package:rogapp/pages/destination/destination_controller.dart'; -// import 'package:rogapp/pages/destination_map/destination_map_page.dart'; -// import 'package:rogapp/pages/drawer/drawer_page.dart'; -// import 'package:rogapp/pages/index/index_controller.dart'; -// import 'package:rogapp/routes/app_pages.dart'; -// import 'package:rogapp/widgets/destination_widget.dart'; - -// class XDestnationPage extends StatelessWidget { -// XDestnationPage({Key? key}) : super(key: key); - -// final DestinationController destinationController = -// Get.find(); - -// final IndexController indexController = Get.find(); - -// final List _items = List.generate(50, (int index) => index); - -// Future showCurrentPosition() async { -// LocationPermission permission = await Geolocator.checkPermission(); -// if (permission != LocationPermission.whileInUse || -// permission != LocationPermission.always) { -// permission = await Geolocator.requestPermission(); -// } -// Position position = await Geolocator.getCurrentPosition( -// desiredAccuracy: LocationAccuracy.high, -// forceAndroidLocationManager: true); -// indexController.rogMapController -// .move(LatLng(position.latitude, position.longitude), 14); -// } - -// Image getImage(int index) { -// if (destinationController.destinations[index].photos == null || -// destinationController.destinations[index].photos == "") { -// return const Image(image: AssetImage('assets/images/empty_image.png')); -// } else { -// return Image( -// image: -// NetworkImage(destinationController.destinations[index].photos!)); -// } -// } - -// Widget getRoutingImage(int route) { -// switch (route) { -// case 0: -// return const Image( -// image: AssetImage('assets/images/p4_9_man.png'), -// width: 35.0, -// ); -// case 1: -// return const Image( -// image: AssetImage('assets/images/p4_8_car.png'), -// width: 35.0, -// ); -// case 2: -// return const Image( -// image: AssetImage('assets/images/p4_10_train.png'), -// width: 35.0, -// ); -// default: -// return const Image( -// image: AssetImage('assets/images/p4_9_man.png'), -// width: 35.0, -// ); -// } -// } - -// @override -// Widget build(BuildContext context) { -// return WillPopScope( -// onWillPop: () async { -// indexController.switchPage(AppPages.INITIAL); -// return false; -// }, -// child: Scaffold( -// drawer: DrawerPage(), -// bottomNavigationBar: BottomAppBar( -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Padding( -// padding: const EdgeInsets.only(left: 13.0), -// child: InkWell( -// child: Obx((() => getRoutingImage( -// destinationController.travelMode.value))), -// onTap: () { -// Get.bottomSheet( -// Obx( -// () => ListView( -// children: [ -// Padding( -// padding: const EdgeInsets.only( -// top: 30.0, bottom: 30), -// child: Center( -// child: Text( -// "select_travel_mode".tr, -// style: const TextStyle( -// fontSize: 22.0, -// color: Colors.red, -// fontWeight: FontWeight.bold), -// ), -// ), -// ), -// ListTile( -// selected: -// destinationController.travelMode.value == -// 0 -// ? true -// : false, -// selectedTileColor: Colors.amber.shade200, -// leading: const Image( -// image: AssetImage( -// 'assets/images/p4_9_man.png'), -// ), -// title: Text("walking".tr), -// onTap: () { -// destinationController.travelMode.value = 0; -// destinationController -// .populateDestinations(); -// Get.back(); -// }, -// ), -// ListTile( -// selected: -// destinationController.travelMode.value == -// 1 -// ? true -// : false, -// selectedTileColor: Colors.amber.shade200, -// leading: const Image( -// image: AssetImage( -// 'assets/images/p4_8_car.png'), -// ), -// title: Text("driving".tr), -// onTap: () { -// destinationController.travelMode.value = 1; -// destinationController -// .populateDestinations(); -// Get.back(); -// }, -// ), -// // ListTile( -// // selected: destinationController.travelMode == 2 ? true : false, -// // selectedTileColor: Colors.amber.shade200, -// // leading: Image(image: AssetImage('assets/images/p4_10_train.png'),), -// // title: Text("transit".tr), -// // onTap:(){ -// // destinationController.travelMode.value = 2; -// // destinationController.PopulateDestinations(); -// // Get.back(); -// // }, -// // ), -// ], -// ), -// ), -// isScrollControlled: false, -// backgroundColor: Colors.white, -// ); -// //destinationController.PopulateDestinations(); -// }), -// ), -// IconButton( -// icon: const Icon( -// Icons.travel_explore, -// size: 35, -// ), -// onPressed: () { -// indexController.switchPage(AppPages.INITIAL); -// }), -// ], -// ), -// ), -// floatingActionButton: FloatingActionButton( -// onPressed: () { -// //print("######"); -// indexController.toggleDestinationMode(); -// }, -// tooltip: 'Increment', -// elevation: 4.0, -// child: Obx(() => indexController.desinationMode.value == 1 -// ? const Image(image: AssetImage('assets/images/list2.png')) -// : const Image(image: AssetImage('assets/images/map.png'))), -// ), -// floatingActionButtonLocation: -// FloatingActionButtonLocation.centerDocked, -// appBar: AppBar( -// automaticallyImplyLeading: true, -// title: Text("app_title".tr), -// actions: [ -// InkWell( -// onTap: () { -// Get.toNamed(AppPages.CAMERA_PAGE); -// }, -// child: destinationController.isInRog.value == true -// ? Image.asset( -// "assets/images/basic-walking.gif", -// height: 10.0, -// ) -// : destinationController.isAtGoal.value == true -// ? IconButton( -// onPressed: () { -// Get.toNamed(AppPages.CAMERA_PAGE); -// }, -// icon: const Icon(Icons.assistant_photo), -// ) -// : IconButton( -// onPressed: () { -// Get.toNamed(AppPages.CAMERA_PAGE); -// }, -// icon: const Icon(Icons.accessibility), -// ), -// ), -// // Obx(() => -// // Text(indexController.connectionStatusName.value) -// // ), -// Obx( -// () => ToggleButtons( -// disabledColor: Colors.grey.shade200, -// selectedColor: Colors.red, -// onPressed: (int index) { -// destinationController.isGpsSelected.value = -// !destinationController.isGpsSelected.value; -// if (destinationController.isGpsSelected.value) { -// destinationController.chekcs = 0; -// destinationController.skipGps = false; -// //destinationController.resetRogaining(); -// } -// }, -// isSelected: [destinationController.isGpsSelected.value], -// children: const [ -// Icon( -// Icons.explore, -// size: 35.0, -// ) -// ], -// ), -// ), -// // IconButton(onPressed: (){ -// // showCurrentPosition(); -// // }, -// // icon: Icon(Icons.location_on_outlined)) -// ], -// ), -// body: Obx(() => indexController.desinationMode.value == 0 -// ? DestinationWidget() -// : DestinationMapPage())), -// ); -// } -// } diff --git a/lib/pages/destination_map/destination_map_controller.dart b/lib/pages/destination_map/destination_map_controller.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/pages/destination_map/destination_map_page.dart b/lib/pages/destination_map/destination_map_page.dart index 75c9b05..1fd0941 100644 --- a/lib/pages/destination_map/destination_map_page.dart +++ b/lib/pages/destination_map/destination_map_page.dart @@ -34,6 +34,8 @@ class DestinationMapPage extends StatelessWidget { return pts; } + // 要検討:マーカーのタップイベントを処理する際に、エラーハンドリングが不十分です。例外が発生した場合の処理を追加することをお勧めします。 + // List? getMarkers() { List pts = []; int index = -1; @@ -123,6 +125,8 @@ class DestinationMapPage extends StatelessWidget { ))); } + // 要検討:MapOptionsのboundsプロパティにハードコードされた座標が使用されています。これを動的に設定できるようにすることを検討してください。 + // FlutterMap travelMap() { return FlutterMap( mapController: indexController.rogMapController, diff --git a/lib/pages/drawer/drawer_binding.dart b/lib/pages/drawer/drawer_binding.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/pages/drawer/drawer_page.dart b/lib/pages/drawer/drawer_page.dart index ef33299..e8f1c61 100644 --- a/lib/pages/drawer/drawer_page.dart +++ b/lib/pages/drawer/drawer_page.dart @@ -11,6 +11,8 @@ class DrawerPage extends StatelessWidget { final IndexController indexController = Get.find(); + // 要検討:URLの起動に失敗した場合のエラーハンドリングが不十分です。適切なエラーメッセージを表示するなどの処理を追加してください。 + // void _launchURL(url) async { if (!await launchUrl(url)) throw 'Could not launch $url'; } @@ -90,6 +92,8 @@ class DrawerPage extends StatelessWidget { leading: const Icon(Icons.password), title: const Text("リセット"), onTap: () { + // 要検討:リセット操作の確認メッセージをローカライズすることを検討してください。 + // Get.defaultDialog( title: "よろしいですか、リセットしますか?", middleText: "これにより、すべてのゲーム データが削除され、すべての状態が削除されます", @@ -132,6 +136,8 @@ class DrawerPage extends StatelessWidget { ), indexController.currentUser.isNotEmpty ? ListTile( + // 要検討:アカウント削除のリクエストが失敗した場合のエラーハンドリングを追加することをお勧めします。 + // leading: const Icon(Icons.delete_forever), title: Text("ユーザーデータを削除する".tr), onTap: () { diff --git a/lib/pages/gps/gps_page.dart b/lib/pages/gps/gps_page.dart index 838f07f..6cbb459 100644 --- a/lib/pages/gps/gps_page.dart +++ b/lib/pages/gps/gps_page.dart @@ -31,6 +31,8 @@ class _GpsPageState extends State { loadGpsData(); } + // 要検討:GPSデータの読み込みに失敗した場合のエラーハンドリングが不十分です。適切なエラーメッセージを表示するなどの処理を追加してください。 + // void loadGpsData() async { final team_name = indexController.currentUser[0]["user"]['team_name']; final event_code = indexController.currentUser[0]["user"]["event_code"]; @@ -41,6 +43,8 @@ class _GpsPageState extends State { //print("--- gps data ${data} ----"); } + // 要検討:マーカーの形状を決定する際に、マジックナンバーが使用されています。定数を使用するなどして、コードの可読性を向上させることを検討してください。 + // Widget getMarkerShape(GpsData i) { return Row( mainAxisAlignment: MainAxisAlignment.start, diff --git a/lib/pages/history/history_page.dart b/lib/pages/history/history_page.dart index 1e0e6d2..31ca1c7 100644 --- a/lib/pages/history/history_page.dart +++ b/lib/pages/history/history_page.dart @@ -24,6 +24,8 @@ class _HistoryPageState extends State { child: Column( children: [ FutureBuilder( + // 要検討:スナップショットのエラーハンドリングが行われていますが、具体的なエラーメッセージを表示するようにすることをお勧めします。 + // future: db.getDestinations(), builder: (BuildContext context, AsyncSnapshot> snapshot) { @@ -49,6 +51,7 @@ class _HistoryPageState extends State { return Padding( padding: const EdgeInsets.all(8.0), child: CustomWidget( + // 要検討:画像のサイズがハードコードされています。画像のサイズを動的に設定できるようにすることを検討してください。 title: dests[index].name!, subtitle: "${dests[index].sub_loc_id} : ${dests[index].name}", diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index 779b2ee..3ab42bb 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:rogapp/pages/search/search_page.dart'; +// 要検討:SearchPageへのナビゲーションにNavigator.pushを使用していますが、一貫性のためにGet.toやGet.toNamedを使用することを検討してください。 +// class HomePage extends GetView{ const HomePage({Key? key}) : super(key: key); diff --git a/lib/pages/index/index_controller.dart b/lib/pages/index/index_controller.dart index e27f8ee..33e6bc3 100644 --- a/lib/pages/index/index_controller.dart +++ b/lib/pages/index/index_controller.dart @@ -166,6 +166,8 @@ class IndexController extends GetxController { return LatLngBounds(LatLng(x1!, y1!), LatLng(x0!, y0!)); } + // 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。 + // void login(String email, String password, BuildContext context) { AuthService.login(email, password).then((value) { print("------- logged in user details ######## $value ###### --------"); @@ -189,6 +191,8 @@ class IndexController extends GetxController { }); } + // 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。 + // void changePassword( String oldpassword, String newpassword, BuildContext context) { String token = currentUser[0]['token']; @@ -230,6 +234,8 @@ class IndexController extends GetxController { cats.clear(); } + // 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。 + // void register(String email, String password, BuildContext context) { AuthService.register(email, password).then((value) { if (value.isNotEmpty) { @@ -345,14 +351,20 @@ class IndexController extends GetxController { // 2024-04-03 Akira .. Update the code . See ticket 2800. // + // 2024-4-8 Akira : See 2809 + // IndexControllerクラスでは、Future.delayedの呼び出しをunawaitedで囲んで、非同期処理の結果を待たずに先に進むようにしました。これにより、メモリリークを防ぐことができます + // + // 要検討:Future.delayedを使用して非同期処理を待たずに先に進むようにしていますが、これによってメモリリークが発生する可能性があります。非同期処理の結果を適切に処理することを検討してください。 + // void loadLocationsBound() async { if (isCustomAreaSelected.value == true) { return; } // Akira 追加:2024-4-6 #2800 - await waitForMapControllerReady(); // MapControllerの初期化が完了するまで待機 + //await waitForMapControllerReady(); // MapControllerの初期化が完了するまで待機 // Akira 追加:2024-4-6 #2800 + // ==> remove 2024-4-8 locations.clear(); String cat = currentCat.isNotEmpty ? currentCat[0] : ""; @@ -375,22 +387,25 @@ class IndexController extends GetxController { isLoading.value = true; // ローディング状態をtrueに設定 - Future.delayed(const Duration(seconds: 1), () async { +// unawaited( Future.delayed(const Duration(seconds: 1), () async { +// remove //print("bounds --- (${bounds.southWest.latitude},${bounds.southWest.longitude}),(${bounds.northWest.latitude},${bounds.northWest.longitude}),(${bounds.northEast.latitude},${bounds.northEast.longitude}),(${bounds.southEast.latitude},${bounds.southEast.longitude})"); - var value = await LocationService.loadLocationsBound( - bounds.southWest.latitude, - bounds.southWest.longitude, - bounds.northWest.latitude, - bounds.northWest.longitude, - bounds.northEast.latitude, - bounds.northEast.longitude, - bounds.southEast.latitude, - bounds.southEast.longitude, - cat - ); - if ( value == null ) { + // 要検討:APIからのレスポンスがnullの場合のエラーハンドリングが不十分です。適切なエラーメッセージを表示するなどの処理を追加してください。 + try { + final value = await LocationService.loadLocationsBound( + bounds.southWest.latitude, + bounds.southWest.longitude, + bounds.northWest.latitude, + bounds.northWest.longitude, + bounds.northEast.latitude, + bounds.northEast.longitude, + bounds.southEast.latitude, + bounds.southEast.longitude, + cat + ); + if (value == null) { // APIからのレスポンスがnullの場合 print("LocationService.loadLocationsBound からの回答がnullのため、マップをリロード"); //DestinationController destinationController = Get.find(); // 追加 @@ -399,32 +414,41 @@ class IndexController extends GetxController { // destinationController.fixMapBound(tk); // 追加 //} // 追加 return; - } - isLoading.value = false; // ローディング状態をfalseに設定 - - if (value!=null && value.features.isEmpty) { + } + isLoading.value = false; // ローディング状態をfalseに設定 + + if (value != null && value.features.isEmpty) { if (showPopup == false) { return; } Get.snackbar( "Too many Points", "please zoom in", - icon: const Icon(Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue), + icon: const Icon( + Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue), snackPosition: SnackPosition.TOP, duration: const Duration(seconds: 3), backgroundColor: Colors.yellow, ); showPopup = false; } - if (value!=null && value.features.isNotEmpty) { + if (value != null && value.features.isNotEmpty) { locations.add(value); } - - }); + } catch ( e) { + print("Error in loadLocationsBound: $e"); + // エラーが発生した場合のリトライ処理や適切なエラーメッセージの表示を行う + // 例えば、一定時間後に再度loadLocationsBound()を呼び出すなど + + + })); } //===Akira 追加:2024-4-6 #2800 + // 要検討:MapControllerの初期化が完了するまで待機していますが、タイムアウトを設定することを検討してください。 + // 初期化に時間がかかりすぎる場合、ユーザーにわかりやすいメッセージを表示するようにしてください。 + // Future waitForMapControllerReady() async { if (!isMapControllerReady.value) { await Future.doWhile(() async { diff --git a/lib/pages/index/index_page.dart b/lib/pages/index/index_page.dart index 2bd588a..f08f17b 100644 --- a/lib/pages/index/index_page.dart +++ b/lib/pages/index/index_page.dart @@ -22,6 +22,9 @@ import 'package:rogapp/utils/location_controller.dart'; // 全体的に、index_page.dartはアプリのメインページの構造を定義し、他のコンポーネントやページへの橋渡しを行っているファイルです。 // +// 要検討:GPSデータの表示アイコンをタップした際のエラーハンドリングを追加することをお勧めします。 +// MapWidgetとListWidgetの切り替えにObxを使用していますが、パフォーマンスを考慮して、必要な場合にのみウィジェットを再構築するようにしてください。 +// DestinationControllerのisSimulationModeを使用してGPS信号の強弱をシミュレーションしていますが、本番環境では適切に実際のGPS信号を使用するようにしてください。 // IndexPageクラスは、GetViewを継承したStatelessWidgetです。このクラスは、アプリのメインページを表すウィジェットです。 // diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 67127f8..b18eef3 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -2,6 +2,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:rogapp/routes/app_pages.dart'; +// 要検討:ログインボタンとサインアップボタンの配色を見直すことを検討してください。現在の配色では、ボタンの役割がわかりにくい可能性があります。 +// ボタンのテキストをローカライズすることを検討してください。 +// class LandingPage extends StatefulWidget { const LandingPage({ Key? key }) : super(key: key); diff --git a/lib/pages/loading/loading_page.dart b/lib/pages/loading/loading_page.dart index 82951e1..e4721d7 100644 --- a/lib/pages/loading/loading_page.dart +++ b/lib/pages/loading/loading_page.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; class LoadingPage extends StatelessWidget { const LoadingPage({Key? key}) : super(key: key); + // 要検討:ローディングインジケーターの値を固定値(0.8)にしていますが、実際のローディング進捗に合わせて動的に変更することを検討してください。 + // @override Widget build(BuildContext context) { return Container( diff --git a/lib/pages/login/login_page.dart b/lib/pages/login/login_page.dart index 50a1538..07b2b52 100644 --- a/lib/pages/login/login_page.dart +++ b/lib/pages/login/login_page.dart @@ -3,6 +3,10 @@ import 'package:get/get.dart'; import 'package:rogapp/pages/index/index_controller.dart'; import 'package:rogapp/routes/app_pages.dart'; +// 要検討:ログインボタンとサインアップボタンの配色を見直すことを検討してください。現在の配色では、ボタンの役割がわかりにくい可能性があります。 +// エラーメッセージをローカライズすることを検討してください。 +// ログイン処理中にエラーが発生した場合のエラーハンドリングを追加することをお勧めします。 +// class LoginPage extends StatelessWidget { final IndexController indexController = Get.find(); diff --git a/lib/pages/login_popup/login_popup_page.dart b/lib/pages/login_popup/login_popup_page.dart index fa2fea0..5f50fe1 100644 --- a/lib/pages/login_popup/login_popup_page.dart +++ b/lib/pages/login_popup/login_popup_page.dart @@ -3,6 +3,10 @@ import 'package:get/get.dart'; import 'package:rogapp/pages/index/index_controller.dart'; import 'package:rogapp/routes/app_pages.dart'; +// 要検討:ログインボタンとサインアップボタンの配色を見直すことを検討してください。現在の配色では、ボタンの役割がわかりにくい可能性があります。 +// エラーメッセージをローカライズすることを検討してください。 +// ポップアップを閉じるボタンを追加することを検討してください。 +// class LoginPopupPage extends StatelessWidget { LoginPopupPage({Key? key}) : super(key: key); diff --git a/lib/pages/permission/permission.dart b/lib/pages/permission/permission.dart index fd692a6..d104f8d 100644 --- a/lib/pages/permission/permission.dart +++ b/lib/pages/permission/permission.dart @@ -70,6 +70,8 @@ class _PermissionHandlerScreenState extends State { )); } + // 要検討:位置情報の許可が拒否された場合、適切なエラーメッセージを表示することを検討してください。 + // Future requestPermission() async { PermissionStatus permission = await Permission.location.status; if (permission == PermissionStatus.permanentlyDenied) { @@ -93,6 +95,8 @@ class _PermissionHandlerScreenState extends State { ); } + // 要検討:ユーザーが位置情報の許可を拒否し続けた場合の対処方法を明確にすることをお勧めします。 + // void showPermanentAlert() { showDialog( context: context, diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart index 72f058f..ddd5b36 100644 --- a/lib/services/auth_service.dart +++ b/lib/services/auth_service.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:rogapp/model/auth_user.dart'; +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; import '../utils/const.dart'; @@ -90,16 +92,35 @@ class AuthService { String url = '$serverUrl/api/login/'; //print('++++++++$url'); //String url = 'http://localhost:8100/api/login/'; - final http.Response response = await http.post( - Uri.parse(url), - headers: { - 'Content-Type': 'application/json; charset=UTF-8', - }, - body: jsonEncode({'email': email, 'password': password}), - ); + try { + final http.Response response = await http.post( + Uri.parse(url), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + body: jsonEncode( + {'email': email, 'password': password}), + ); - if (response.statusCode == 200) { - cats = json.decode(utf8.decode(response.bodyBytes)); + if (response.statusCode == 200) { + cats = json.decode(utf8.decode(response.bodyBytes)); + } else { + print('Login failed with status code: ${response.statusCode}'); + cats = {}; + } + } catch( e ){ + print('Error in login: $e'); + Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした"); + Get.snackbar( + "通信エラーがおきました", + "サーバーと通信できませんでした", + icon: const Icon( + Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue), + snackPosition: SnackPosition.TOP, + duration: const Duration(seconds: 3), + backgroundColor: Colors.yellow, + ); + cats = {}; } return cats; } diff --git a/lib/services/device_info_service.dart b/lib/services/device_info_service.dart index aa7b24d..dcbb325 100644 --- a/lib/services/device_info_service.dart +++ b/lib/services/device_info_service.dart @@ -1,5 +1,5 @@ import 'dart:io'; -//import 'package:device_info/device_info.dart'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart'; diff --git a/lib/services/error_service.dart b/lib/services/error_service.dart index c432769..3c3a9ba 100644 --- a/lib/services/error_service.dart +++ b/lib/services/error_service.dart @@ -9,7 +9,7 @@ class ErrorService { final String errorMessage = error.toString(); final String stackTraceString = stackTrace.toString(); final String estimatedCause = _estimateErrorCause(errorMessage); - // final String deviceInfo = await _getDeviceInfo(); + //final String deviceInfo = await _getDeviceInfo(); final Uri url = Uri.parse('https://rogaining.sumasen.net/report-error'); final response = await http.post( @@ -44,5 +44,17 @@ class ErrorService { return '不明なエラー'; } } + + /* + // 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810 + // + static void reportMemoryError(String message, StackTrace stackTrace) async { + final errorDetails = FlutterErrorDetails( + exception: Exception(message), + stack: stackTrace, + ); + await reportError(errorDetails.exception, errorDetails.stack ?? StackTrace.current, deviceInfo); + } + */ } diff --git a/lib/services/external_service.dart b/lib/services/external_service.dart index a3b1905..c0d8c1d 100644 --- a/lib/services/external_service.dart +++ b/lib/services/external_service.dart @@ -114,64 +114,69 @@ class ExternalService { //print("~~~~ before calling api 1 ~~~~"); - final http.Response response = await http.post( - Uri.parse(url1), - headers: { - 'Content-Type': 'application/json; charset=UTF-8', - 'Authorization': 'Token $token' - }, - // 'id', 'user', 'goalimage', 'goaltime', 'team_name', 'event_code','cp_number' - body: jsonEncode({ - 'user': userId.toString(), - 'team_name': teamname, - 'event_code': eventcode, - 'checkinimage': im1_64, - 'checkintime': checkinTime, - 'cp_number': cp.toString() - }), - ); - - res = json.decode(utf8.decode(response.bodyBytes)); - //print("~~~~ api1 result $res ~~~~"); - //print("-----@@@@@ checkin $_res -----"); - - if (response.statusCode == 201) { - //print("~~~~ image from api1 ${res["checkinimage"].toString()} ~~~~"); - //print('---- toekn is ${token} -----'); - //print("~~~~ token is $token ~~~~"); - //print("~~~~ before callling api2 ~~~~"); - final http.Response response2 = await http.post( - Uri.parse(url), + try { + final http.Response response = await http.post( + Uri.parse(url1), headers: { 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': 'Token $token' }, + // 'id', 'user', 'goalimage', 'goaltime', 'team_name', 'event_code','cp_number' body: jsonEncode({ + 'user': userId.toString(), + 'team_name': teamname, + 'event_code': eventcode, + 'checkinimage': im1_64, + 'checkintime': checkinTime, + 'cp_number': cp.toString() + }), + ); + + res = json.decode(utf8.decode(response.bodyBytes)); + //print("~~~~ api1 result $res ~~~~"); + //print("-----@@@@@ checkin $_res -----"); + + if (response.statusCode == 201) { + //print("~~~~ image from api1 ${res["checkinimage"].toString()} ~~~~"); + //print('---- toekn is ${token} -----'); + //print("~~~~ token is $token ~~~~"); + //print("~~~~ before callling api2 ~~~~"); + final http.Response response2 = await http.post( + Uri.parse(url), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + body: jsonEncode({ + 'team_name': teamname, + 'cp_number': cp.toString(), + 'event_code': eventcode, + 'image': res["checkinimage"].toString().replaceAll( + 'http://localhost:8100', 'http://rogaining.sumasen.net') + }), + ); + var vv = jsonEncode({ 'team_name': teamname, 'cp_number': cp.toString(), 'event_code': eventcode, 'image': res["checkinimage"].toString().replaceAll( 'http://localhost:8100', 'http://rogaining.sumasen.net') - }), - ); - var vv = jsonEncode({ - 'team_name': teamname, - 'cp_number': cp.toString(), - 'event_code': eventcode, - 'image': res["checkinimage"].toString().replaceAll( - 'http://localhost:8100', 'http://rogaining.sumasen.net') - }); - //print("~~~~ api 2 values $vv ~~~~"); - //print("--json-- $vv"); - //print("--- checnin response ${response2.statusCode}----"); - if (response2.statusCode == 200) { - res = json.decode(utf8.decode(response2.bodyBytes)); - //print('----checkin res _res : $res ----'); - if (res["status"] == "ERROR") { - Get.snackbar("エラーがおきました", res["detail"]); + }); + //print("~~~~ api 2 values $vv ~~~~"); + //print("--json-- $vv"); + //print("--- checnin response ${response2.statusCode}----"); + if (response2.statusCode == 200) { + res = json.decode(utf8.decode(response2.bodyBytes)); + //print('----checkin res _res : $res ----'); + if (res["status"] == "ERROR") { + Get.snackbar("エラーがおきました", res["detail"]); + } } + } else { + Get.snackbar("サーバーエラーがおきました", "サーバーと通信できませんでした"); } - } else { - Get.snackbar("エラーがおきました", "サーバーに更新できませんでした"); + } catch( e ) { + print('Error in makeCheckpoint: $e'); + Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした"); } } } else { diff --git a/lib/utils/location_controller.dart b/lib/utils/location_controller.dart index 8108f88..4c2efe3 100644 --- a/lib/utils/location_controller.dart +++ b/lib/utils/location_controller.dart @@ -77,6 +77,9 @@ class LocationController extends GetxController { // エラーが発生した場合は、locationMarkerPositionStreamControllerにエラーを追加します。 // ストリームが一時停止中の場合は、ストリームを再開します。 // + // 2024-4-8 Akira : See 2809 + // stopPositionStreamメソッドを追加して、既存のストリームをキャンセルするようにしました。また、ストリームが完了したらnullに設定し、エラー発生時にストリームをキャンセルするようにしました。 + // void startPositionStream() async { // Check for location service and permissions before starting the stream bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); @@ -161,8 +164,7 @@ class LocationController extends GetxController { await positionStream?.cancel(); - positionStream = - Geolocator.getPositionStream(locationSettings: locationOptions).listen( + positionStream = Geolocator.getPositionStream(locationSettings: locationOptions).listen( (Position? position) { if (position != null) { final LocationMarkerPosition locationMarkerPosition = @@ -170,14 +172,18 @@ class LocationController extends GetxController { latitude: position.latitude, longitude: position.longitude, accuracy: position.accuracy); - locationMarkerPositionStreamController.add(locationMarkerPosition); - } else { - locationMarkerPositionStreamController.add(null); - } - }, - onError: (e) { - locationMarkerPositionStreamController.addError(e); - }, + locationMarkerPositionStreamController.add(locationMarkerPosition); + } else { + locationMarkerPositionStreamController.add(null); + } + }, + onError: (e) { + locationMarkerPositionStreamController.addError(e); + }, + onDone: () { + positionStream = null; // ストリームが完了したらnullに設定 + }, + cancelOnError: true // エラー発生時にストリームをキャンセル ); // Resume stream if it was paused previously @@ -192,10 +198,14 @@ class LocationController extends GetxController { // positionStreamが存在する場合、ストリームを一時停止します。 // isStreamPausedフラグをtrueに設定します。 // - void stopPositionStream() { + void stopPositionStream() async { if (positionStream != null) { - positionStream!.pause(); - isStreamPaused = true; + // updated Akira 2024-4-8 + await positionStream!.cancel(); + positionStream = null; + + //positionStream!.pause(); + //isStreamPaused = true; } } diff --git a/lib/widgets/custom_icons.dart b/lib/widgets/custom_icons.dart new file mode 100644 index 0000000..26d9333 --- /dev/null +++ b/lib/widgets/custom_icons.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; + +class CustomIcons { + static const _fontFamily = 'CustomIcons'; + + static const IconData gps_signal_low = IconData(0xe900, fontFamily: _fontFamily); + static const IconData gps_signal_middle = IconData(0xe913, fontFamily: _fontFamily); + static const IconData gps_signal_high = IconData(0xe91d, fontFamily: _fontFamily); +} diff --git a/lib/widgets/gps_status.dart b/lib/widgets/gps_status.dart index 68a79dc..c27f522 100644 --- a/lib/widgets/gps_status.dart +++ b/lib/widgets/gps_status.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:rogapp/widgets/GameState/Colors.dart'; import 'package:rogapp/pages/destination/destination_controller.dart'; -//import 'package:rogapp/widgets/custom_icons.dart'; +import 'package:rogapp/widgets/custom_icons.dart'; enum GPSStatus { high, middle, low } @@ -30,19 +30,19 @@ class GpsSignalStrengthIndicator extends StatelessWidget { case 'high': backgroundColor = Colors.green; iconData = Icons.signal_cellular_alt; - //iconData = CustomIcons.gps_signal_high_0; + // iconData = CustomIcons.gps_signal_high; text = 'GPS 強'; break; case 'medium': backgroundColor = Colors.orange; iconData = Icons.signal_cellular_alt_2_bar; - //iconData = CustomIcons.gps_signal_middle_0; + // iconData = CustomIcons.gps_signal_middle; text = 'GPS 中'; break; default: backgroundColor = Colors.grey; // Fallback color iconData = Icons.signal_cellular_connected_no_internet_4_bar; - //iconData = CustomIcons.gps_signal_low_0; + // iconData = CustomIcons.gps_signal_low; text = 'GPS 弱'; } diff --git a/lib/widgets/map_widget.dart b/lib/widgets/map_widget.dart index bc83327..20c1896 100644 --- a/lib/widgets/map_widget.dart +++ b/lib/widgets/map_widget.dart @@ -18,6 +18,21 @@ import 'package:rogapp/widgets/bottom_sheet_new.dart'; import 'package:rogapp/widgets/current_position_widget.dart'; import 'package:rogapp/widgets/game_state_view.dart'; +// map_widget.dartファイルは、アプリ内の地図表示を担当するウィジェットを定義しています。以下に、主要な部分を解説します。 +// 地図表示に関連する主要な機能を提供しています。以下のような機能が含まれています。 +// +// 地図の表示と操作 +// マーカーの表示とカスタマイズ +// ルートの表示 +// 現在位置の表示 +// アイドル状態の処理 +// ローディングインジケーターの表示 +// ゲーム状態の表示 +// 現在位置ボタンの表示 + + +// StatefulWidgetを継承したクラスで、地図表示のメインウィジェットです。 +// class MapWidget extends StatefulWidget { MapWidget({Key? key}) : super(key: key); @@ -25,16 +40,23 @@ class MapWidget extends StatefulWidget { State createState() => _MapWidgetState(); } +// MapWidgetの状態を管理するクラスです。 +// class _MapWidgetState extends State { final IndexController indexController = Get.find(); - + // IndexControllerのインスタンスを保持します。 final DestinationController destinationController = Get.find(); + // DestinationControllerのインスタンスを保持します。 final LocationController locationController = Get.find(); + // LocationControllerのインスタンスを保持します。 - StreamSubscription? subscription; - Timer? _timer; + StreamSubscription? subscription; // 地図イベントの購読を保持します。 + Timer? _timer; // アイドル状態のタイマーを保持します。 + // 地図上のマーカーのUIを生成するメソッドです。 + // GeoJSONFeatureを受け取り、マーカーのUIを返します。 + // Widget getMarkerShape(GeoJSONFeature i, BuildContext context) { GeoJSONMultiPoint p = i.geometry as GeoJSONMultiPoint; //print("lat is ${p.geoSerie!.geoPoints[0].latitude} and lon is ${p.geoSerie!.geoPoints[0].longitude}"); @@ -155,6 +177,9 @@ class _MapWidgetState extends State { ); } + // ルートポイントをLatLngのリストに変換するメソッドです。 + // IndexControllerのroutePointsからLatLngのリストを生成しています。 + // List? getPoints() { //print("##### --- route point ${indexController.routePoints.length}"); List pts = []; @@ -165,21 +190,31 @@ class _MapWidgetState extends State { return pts; } + // ウィジェットの初期化時に呼び出されるメソッドです。 + // _startIdleTimerメソッドを呼び出して、アイドル状態のタイマーを開始します。 + // @override void initState() { super.initState(); - _startIdleTimer(); + _startIdleTimer(); // _startIdleTimerメソッドを呼び出してアイドル状態のタイマーを開始しています。 } + // アイドル状態のタイマーを開始するメソッドです。 + // 一定時間後に_centerMapOnUserメソッドを呼び出すようにタイマーを設定しています。 + // void _startIdleTimer() { _timer = Timer(const Duration(milliseconds: (1000 * 10)), _centerMapOnUser); } + // アイドル状態のタイマーをリセットするメソッドです。 + // void _resetTimer() { _timer?.cancel(); _startIdleTimer(); } + // 地図をユーザーの現在位置に中央揃えするメソッドです。 + // void _centerMapOnUser() { assert(() { print("showBottomSheet ${destinationController.shouldShowBottomSheet}"); @@ -192,6 +227,13 @@ class _MapWidgetState extends State { //} } + // ウィジェットのUIを構築するメソッドです。 + // FlutterMapウィジェットを使用して地図を表示します。 + // layersプロパティに、ベースレイヤー、ルートレイヤー、現在位置レイヤー、マーカーレイヤーを設定します。 + // PopupControllerを使用して、ポップアップの制御を行います。 + // IndexControllerのisLoading変数に基づいて、ローディングインジケーターを表示します。 + // GameStateWidgetとCurrentPositionウィジェットを重ねて表示します。 + // @override Widget build(BuildContext context) { // print( @@ -200,18 +242,22 @@ class _MapWidgetState extends State { final PopupController popupController = PopupController(); return Stack( children: [ + // IndexControllerのisLoading変数に基づいて、ローディングインジケーターを表示します。 + // isLoadingがtrueの場合はCircularProgressIndicatorを表示し、falseの場合は地図を表示します。 Obx(() => indexController.isLoading.value == true ? const Padding( padding: EdgeInsets.only(top: 60.0), child: CircularProgressIndicator(), ) : FlutterMap( + // 地図の表示を担当 mapController: indexController.mapController, options: MapOptions( + // 地図の初期設定(最大ズームレベル、初期位置、ズームレベルなど)を行っています。 maxZoom: 18.4, onMapReady: () { - // print("Map controller ready!!"); ... working corretly - indexController.isMapControllerReady.value = true; // Added Akira,2024-4-6 for #2800 + // print("Map controller ready!!"); ... working corretly + indexController.isMapControllerReady.value = true; // Added Akira,2024-4-6 for #2800 subscription = indexController.mapController.mapEventStream .listen((MapEvent mapEvent) { @@ -235,6 +281,7 @@ class _MapWidgetState extends State { InteractiveFlag.pinchZoom | InteractiveFlag.drag, onPositionChanged: (MapPosition pos, hasGesture) { + // 地図の位置が変更された際の処理を行います。 //print("map position changed ${pos.center!.latitude}"); if (hasGesture) { _resetTimer(); @@ -249,9 +296,10 @@ class _MapWidgetState extends State { Obx( () => indexController.routePointLenght > 0 ? PolylineLayer( + // ルートの表示を担当 polylines: [ Polyline( - points: getPoints()!, + points: getPoints()!, // ルートのポイントを設定しています。 strokeWidth: 6.0, color: Colors.indigo), ], @@ -259,11 +307,14 @@ class _MapWidgetState extends State { : Container(), ), CurrentLocationLayer( + // 現在位置の表示を担当 positionStream: locationController .locationMarkerPositionStreamController.stream, + // locationMarkerPositionStreamController.streamを設定して、現在位置の更新を監視しています。 alignDirectionOnUpdate: AlignOnUpdate.never, turnOnHeadingUpdate: TurnOnHeadingUpdate.never, style: const LocationMarkerStyle( + // styleプロパティで、現在位置のマーカーのスタイルを設定しています。 marker: DefaultLocationMarker( child: Icon( Icons.navigation, @@ -277,6 +328,7 @@ class _MapWidgetState extends State { indexController.locations.isNotEmpty && indexController.locations[0].features.isNotEmpty ? MarkerLayer( + // マーカーの表示を担当 markers: indexController.locations[0].features.map((i) { //print("i si ${i.properties!['location_id']}"); @@ -293,13 +345,29 @@ class _MapWidgetState extends State { point: LatLng( p.coordinates[0][1], p.coordinates[0][0]), child: getMarkerShape(i, context)); + // マーカーのUIを生成しています。 + // マーカーのアイコン、ラベル、色などをカスタマイズしています。 }).toList(), ) : const Center(child: CircularProgressIndicator()), ], )), const Positioned(top: 0, left: 0, child: GameStateWidget()), - const Positioned(bottom: 10, right: 10, child: CurrentPosition()) + // ゲーム状態の表示を担当。ゲームの状態(開始、終了など)を表示するカスタムウィジェットです。 + const Positioned(bottom: 10, right: 10, child: CurrentPosition()), + // 現在位置ボタンの表示を担当。現在位置に移動するためのボタンを表示するカスタムウィジェットです。 + StreamBuilder( + stream: locationController.locationMarkerPositionStream, + builder: (context, snapshot) { + if (snapshot.hasData) { + print("Display current marker"); + } else { + print("Not display current marker"); + } + return Container(); + }, + ) + // const Positioned( // bottom: 10, // left: 0, diff --git a/pubspec.yaml b/pubspec.yaml index 5c79059..c128997 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -135,6 +135,12 @@ flutter: # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: + + fonts: + - family: CustomIcons + fonts: + - asset: assets/fonts/icomoon.ttf + # fonts: # - family: Schyler # fonts: