From a63d3e43a16a2740af6ab4e855b7fbd15db231ee Mon Sep 17 00:00:00 2001 From: Ming Ming <nkming2@gmail.com> Date: Wed, 17 Nov 2021 22:41:11 +0800 Subject: [PATCH] Add OSM as alternative map provider --- assets/2.0x/gps_map_pin.png | Bin 0 -> 3442 bytes assets/3.0x/gps_map_pin.png | Bin 0 -> 5113 bytes assets/gps_map_pin.png | Bin 0 -> 1674 bytes lib/l10n/app_en.arb | 1 + lib/l10n/untranslated-messages.txt | 9 ++ .../{gps_map.dart => google_gps_map.dart} | 5 +- lib/mobile/platform.dart | 2 +- lib/pref.dart | 8 ++ lib/web/{gps_map.dart => google_gps_map.dart} | 11 +- lib/web/platform.dart | 2 +- lib/widget/gps_map.dart | 124 ++++++++++++++++++ lib/widget/settings.dart | 97 ++++++++++---- lib/widget/viewer_detail_pane.dart | 5 +- pubspec.lock | 63 +++++++++ pubspec.yaml | 1 + 15 files changed, 290 insertions(+), 38 deletions(-) create mode 100644 assets/2.0x/gps_map_pin.png create mode 100644 assets/3.0x/gps_map_pin.png create mode 100644 assets/gps_map_pin.png rename lib/mobile/{gps_map.dart => google_gps_map.dart} (90%) rename lib/web/{gps_map.dart => google_gps_map.dart} (78%) create mode 100644 lib/widget/gps_map.dart diff --git a/assets/2.0x/gps_map_pin.png b/assets/2.0x/gps_map_pin.png new file mode 100644 index 0000000000000000000000000000000000000000..a76280a7b3ee9e9a1b3146d46a14c41835f4006b GIT binary patch literal 3442 zcmV-&4UO`NP)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm001Tw z001Tw0n8z{hyVZp8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H14F5?) zK~#90)tzf>9Mu)a|7T`*{aQN@NJuawc2I&HLqe0-G!<2;)Pky}YNaYwKeb;FY6}gj zs<xtnv_hy*Aw)sYh<>0V6oQmS6xxa^p%5M+_Iek$Nvse^qBH^J;rP9~v$HdEPe0hR zo>_bC^}P4@Y3_LD-m~+cxsP+ty(UB)-nmmgdHzf{3Hc6yH!{#gz$$>60d54K0~iJ{ z48j=*3`oF$B+EzE_w`MLZ2p2!*apl61JcJmTfPn<{Sbt^09@lBn<9XBnejTu<NLaf z9v$)6OizfE02j7zZ^#<OAA{*W0P8%=S|P?Oki|0{eIFh3Fkjb1LV$Pfyfd~sKY0%` zJq+Obxvq&z66#|yBqSLLNrEI1BqA^ah7i!1p&B|=!+>fSm5LGoy&4l@_xeocjBh_^ z5ri(l$*o&&g+wm^*jE0xI$6e&L;}e~0trd3I!}WcS*?g{QA1WMf@fc%5$JIvpMSJ# zaIomcez$}s00VTgXX`JC=@9@4>)(>`IF{GfqcIkDU5+jU#)>LN3k4WFON!$H^n<Sc z{{Ofx$RVK!@ZU|Fni6$&e+GD`^?XAthLsJCXo$r;FH<mMxKO~TT7a+%p@8_F&Q#_V z&kL=Bzy&zj({l}290ah%JSP!hMMEQ&B@zJnYmz1eF6FYw>3Z2;__5CZ%&&bdd=3H? z;PjU^t<;K%Lm+H2&n09TH#8-YkgKoby<k)=;7UGkZyyNHcBIm~2y-<X{t%b|gI!%o zxv}AW25vLYHO1p-ZAwD&`K_-+Uf1w>HV1>n%t^wtovHLsgR(&iq7dG>Q<fU*_gNo) zb3B0?LVWlD&=`wjZA%MclI1Zl?*F*E`+=Zr2t<I7&z=1RKs(HIGM>Qo$s{Pmhi{UQ zB&=<=i@@L~Pj+{IC5ZBUe*&j^dNvCdDNJ`Y>tq>gn_EJC^XH;q7&t#UVd)|9xtJ8& z?6*J3*Drtp5-j#$`r%7NXiYXp?%@MKy)0u@W0U0!wHZQx%<po272srd_xAv7H`6QX z8<3C!sr4Mul1QK>F*7D)(7l7V-@eh$GJSg*3`hii#7x)8F)XXE_p3P1xUQkm`h~_M zVfgwL_$I)qZQFJL*kGntHa7TGl&8p&gligXwtnlAFK+4dt32<={L?Vue)G6qmeJ&a zU&rKfK992#6Btuf5D}In61Zu}60B_SM&xCQI*cfa={q7rNDlz`ktdm#;Y({c*xkKK z0)GZT27uK~Ni0bu7PxDEm>C~jyoi6CJBJI|?3~x!m`q|vTO00Jz1npbcSun%Tu=Z2 z1dPd}W2@GmKCQaSbPjx}f{6LMn11*KpgHdD?H^H9>`tYy=fsJM4<7(7WV6_F;skz^ zN?}BG_pFxM8e=RqmM*>9RfZMtMF0u-nt7az$6a+hFXi)isJ9nq#>cC^=k)kE9`5bM zrF`CTxp7%Wy~Qibgl{^|Y#uxpfB|B{m(6rz+<DcL*L6HGFn}=!Z}X_C;>m#l<Y#$3 zt0!ssa+zm-lb3idz^C2a?XXOuH^!WMIS-sUgNwPG<NH6)<?!0svySg?uyh=V&@s4u z`*O#bRlsur3^LYR(~Fr(v@)uyc<aIi*Y+Gdf8Nm-1OWB2?eP!^bwj0Vo#MFw1Zp>r z<C5gKH<G%18JZ9aU$_985a_>h#nHVoNsz7f8`Ap9S3AS|Mp#g@c_@?f?2iu*dtwd% z9CMLZ%<ejI5}!0Lo(mv|Oa2BoUGb}hf*0lh0EQLC@x78|s6;@c7xvim_ZR{+^VrS2 zo}1oFIkV?~7lGv^B4W><mk;9rsr0=YF6!_WmxDK3UM@!AWxv6@dT|;*24XV;%#OpU zn(G?9``X?3h-|-saMc5IZ1^z{D;X)69alrQU3;xZ76DsUtZ;m<J;;%x{{_fG*!p}< zyOLX1u0)du)lf1XcPxM|1Yr3B2(jo3uwmW0PeCYo%nA-0z{Xe%-)?VT_`(JF&boDu zBkc<IAYY?UD4cd}P#NC$g7)t>h-tt~E4nt{<@555wQF(9a_6J}Tb3`!-D}o3zTf)t z5O93+v188tA{Fq(8_Gb+JTB-JL&X<FCc>`Go3XB?WzqMpTe1YZHgC3%WEY8ISifFM zJI-hx{F)EwHIEfTpQ=k8l8nc(yQc?twzgK~)*vE$wY3$yySr`P%*7&@p;*2E>r3S& zzD!A~#p0WZx<n2@697yUi&*YrLOvl$xVNhdcdc22f1W#sfuW&U1GUCj3}0BW0z2B; zu(r9mLQd6_)ii4qHA9vUxz2PBd<)Py*}ZKafbRo9eJqBy=EYYdl`xobDVM|Ow3l;P zT^&|6HMy#8%K0oiiL6#?zuxQYPx}%n=i8(_G4?S{2~g0dmJZc<6ag(0p*5LAYclCc ze&rZK*xVOHyw8_{;A2>dp(y_Xs5B-pC%9{Y5mg1xR6j+Ayx*^~d=sE+aIgsGr_J<4 zv52Av{(Zj@%otN=Jh8-hsWX-Gd;n(RYn)($`8fck+4K<?ZsDL9Evi=kj{xw5pXK=~ zz)hLVIKY22(_=+-z9pogBbYI2dr9a(M>>7V&oX_Fl#S`)DFCGq?;*u`sEFSTD++YW z+b@9M`CX>(0<0ex7y{^VGo95m<TU5*3BS;Uz=*Z(C%hcQ^3_0M#gnnv9{`*;(?bQt z=4FfmL-qxGied0WL6jSa05={zsxYJUg9^Hiv0|tT)NLrbjtR|T58<h<Oy+#$JG>*X z)e@cQ^vhO%%1}YEuTBh+%XyoV^Ky*j-v?E8U;+>zND@E6RM!rM5V)#%7y00nF;%ts z{R#A7koyb;x?ZTW@1qQW7tQpTS_rjUYOt{N${0x9+~5D=JhymG;0v~NNq!L1-BQNX zVvDf2s@OL05G;5XO@E<55x4-i_VrzcW$jpA*Dx7EgRB~c&E){_-mXlhFK9bLS+bZD zcm_aegn32D2e&zcS*E?)ImrTnZ`1*VB*3;zMq@^4KL$+*jCdG|xDb<C5jo3TH4`4) zn8{oW%m53aE!y3fP9I|6O*1`QP+U!2Rtqy@$m;JQoQ{u-Jze<@e+hNfw8Z!srejG3 zGp+{UEge-0C|bLn0zda-@m;lqDnLg%eTsnR%(UO$Qe%48EDMJ^(&;yRE3gVe-#4IG zr#=Fpw5O+^-crljUjPt-@hjg7tCG+K*!02iQGiR69$8I8-bFB1C3I$t7A-Xm<1bz5 z^g!i1f+2JP0HD69+2$?1;zL_7l+RhiObTomyFD+&0g(`({qW%efqrYI3%ZU;&AY*w zY8V)|4fg1{jROP!^Q-_DL_z=nxVf!uFM#7_df3Y)O16j$8Wpja?=xN15*Y!ef_hPM zQ51CDab&d>U5Ij5#}iT7$U8Cu0Kmm$@^1h>Gt;9k_j>@Qy0+GtE)f06b*3H?DFMEE z_^?jk=gstlR&+IK!+>p(HZflDGsedWkrDs^WL-QDKn14U24kx8#(1)*+T0r~i#@Il z^q9yAFdap4z)ag+#*3q@3j1(+LMT#1PJn4j?g>o@M`0|gVc6pP!Fbja%RDBM0(AEG ze+b}&nI0=HzA+xR-9uM|q8zArafn1x003ad3+8cF(-yVpo0-c7UU(_&f7DQk$O=G` zv=^4fczhAlmgRzxWbF0aK#z#50G+ASFbID))8mV%hHTdo`l9xad#prO005B0Of{q$ zMpYwYo!Ppy2w-}l^3~xJX#qC0w;zOMWL(WxFmCU9=3|ods`r+8N2CRy{re4oUoz8^ znzmq2@1#W}A{>bNf76S!001DEO6#+9A&@sJS3^Z1Y+;5%AkuF?Py+&VrPBi-l=f(t zELI+rS-qYFjIpA;<*#+_iM#*+Ks@7`m@KLlt0C(o4uf8gYTw^VZ3qCA1kjnG%n>=E z2~pllisZ<*oSG2e=KlVE0HqyR=bEmZu%DZ(Z));oYXPsR2?3^{*UY22f_d%d_>K0% zhr?fdPzALk0L`=mnh;Pey&=7<`eDLfgEh`MH6uVrD%A(eesoqBb<Q3~RLC1R7@TG9 zs2KqW5Db3XOj|e8u!=#zk!_hwbQdF+Q8NMn00^aqHLq!<$#(1BL4vp@8ebFNwyW_2 zHgM3~j+!yGADv8+J*?e8O$ks_U%>R*-A~MPPSeY$E3bBDGNJu*W+&8?0MnG-@SHwt z+k>})US#K%niGI{riW873|k~M6C&^XDW~QHKwaHCFn4G#+Zvgq*uO)u$ptkhK*y0I zlT4UvIq9j+-rjRT+vAp+6953fba>V&(A#rd8F^|_0FuP}Wv2`P?}lNETWV4Oku7`( zz`Df=L5TOlvd0ZIDL~iYU={>xn0aql3$5K!lL7#MB*&iwa2DXt1?ax8?QzQg0mWZn U%oodl-2eap07*qoM6N<$g5FYGp#T5? literal 0 HcmV?d00001 diff --git a/assets/3.0x/gps_map_pin.png b/assets/3.0x/gps_map_pin.png new file mode 100644 index 0000000000000000000000000000000000000000..6a1eceabe9dad650a26e5dbb0bd932777236ad1f GIT binary patch literal 5113 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 XdvTjX3CH)a-*$kyvNobZ(K6(JNTh5> literal 0 HcmV?d00001 diff --git a/assets/gps_map_pin.png b/assets/gps_map_pin.png new file mode 100644 index 0000000000000000000000000000000000000000..0920af14e4cb3ab3934d65c7cd512bfed1aed8a7 GIT binary patch literal 1674 zcmV;526g#~P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000vT z000vT0r^KpG5`Po8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11{X<0 zK~!jgy_w%@T*np1KWFZ)c2|}yyN>NBwZR6<wW}C|D%tcG6kG~^sGs_O<RKxYAtdCf z(9ndIhLW^U3Z-q*LPKpxs-)N{xX!YY<;o~dK@Lh|*^weymiFiUF?0H`v8&kH-FsJe z`+Zt==A85W-ZSUS%)LU2m_0fAZKHA)%(oDRQQZlIs4l6IX@kCPy}ma_E?>TrR!m95 z$-l?O&N$&kU<4p*jO+6}V-OICtiyNKIaLFMz&X!z&mMXI%Jr?r-jaZ8<KqW1=qteY zJ#f471+ycUqtBR!=Bg@{C}ceds04v3SQTCl8^H@FW@f7YcL5)ajXiFRysfH_4d!yP zH($Wpg!pC%tYxuQ(`pn7$~BYCp83k<%M0D`=t{u#lPAB9vlGUc{x5GEFx#@(ZrpIE z(O{`wQ-uFytezg8n!1tHM`8ijPMzA9QFql--Fslipvik)QWsx9IS9B_tE#HbR-K+2 zo0_U6v5%MY4am6Yx2WzL8W`9zd4TPGee5mt3-I`WF+WRcpC|*@$Hu;caA8+2$G-k; zNn^FeLZw1E4AddVM@psHxOPc1@VtQAoiB8p7&ym#xy*dIOyFF{`Fr{c_Xs_ogi!1Z z%#M#gYS4wjT+R%&dHSJq{Aq5EcRu+9-&z22p2znN9N-6s50h=vsTQgg%0UojjQ7ZJ zvA7<GSL_UUa0W2jGp#$0RpqDC)1055zfT^(x0ZAB^SpHRDo(Yf{Xo-qHgfK}ae2iS zpy<~C3T;~Eg_}2-Sy^d0{;%a_E-tig_xIbe>Nn%^N>T%l8c<JKueyKSy4BIidu`@q zj6p;c7>Y|Owg7>hrs=#T7Hgebc&9m@h$8HX%PYweTJO|L`eW?Kg-oXHxN{CsDsg!w z$beaKs-|5L9^bvYqn{IP<|yEroLU#s1Bflasm=ml=q?Z9?7@Tdw|T+?*(_%d9cnr5 zM-c!j@?l(F@iSmd5ug@@E$2K^DDd>?C_8hxhsJj0ay&gc%9rx_miBeq6oBevY+i9E zDwq#XjxXem*>`ZqU|YL}wOqP=n;UCu03041<QqdnbUHhITwbRhhL!xl_C1F#UTnnS z)xM%OK)`*V?)8S%CmK;izRgm}dmg9v@8|UX{c+tBSW7*M5aji^<RRf%D1-UAfL-=u z`;U#4rcbpZzer-2NWhU&=_7>SSAu~0=LMGr0&7|KeHG!Yky7bu65GW00Z+VV1nP_R zn$o7FCc$F8hN>#!ew5TUv4G)X@us3LHlj$@!XT;nL#Tuy)i6ZGyn3{FWhSY8VgUew zAN~Zm{aL;4+HGu|pukeCrXsSQjiN;NfP3glz=@feswzK>oHKVC-52y-zd_)vDDH*f z>FLk9@zIq4fMb)BzXK*$8g&h0+_)ZuRb{zecZkeq?ySAiEsw4R2q?%C3M|*_iS1V! zb*!pEd2)De&hM5-*8%{Jl}i5veRD1FwPEA8)zCRseP2P}KUymNWh)%EBmls}JOzYH zwOZ_IUTU^Yz&zQ^WcS#zfFq^SM~eQk7DZBRbI`kohP9M~0F*yAGq^QuSpa}FnI8k; zs^57juQt1ubIv`NM(k7s94{6ZLEfwefktii1*=Lq@Eyv#BUi4>r4c(70RRfGDahS6 z2fg(mXx_L)UQH`*Y66axN`FUnZq4^wZVGoBbrq4Ns&nVkikq4M0aYWv3Y{~RP0mQQ zD8zS8obuY()KuqckBQU-0Axe^8z8*9Nil!^pCgKXoo38b1vJkydcGQlYBv<KQ>7Ay z4&~jiPEUWFX3SIt03iHXK`O!jmQghfajHfQZ=@YAbpevipF`CzZ`jnzVSs?mhW4*% z$4gzn(My-gh)h(2K%Hvy>tql(g$vytncE@#B?N$+SCCp1QMVBejG(Et&W(uuS|t%Y zZvq=pi^BUao{XpO^deL$U+Oo*_3^PAIb#lq2n}mLJyx20tQT>5w1hyBzxmEd!&(8E z=vADa2@rT|!|$FfALyZg%<Afdh?Ie<XUu!OiqkUz!*g@Ks{R4hi^Ij@&0fX%FTzmc UeOYH+tpET307*qoM6N<$f|x8a(*OVf literal 0 HcmV?d00001 diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d8d754a2..b63ef9bc 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -352,6 +352,7 @@ "settingsScreenBrightnessDescription": "Override system brightness level", "settingsForceRotationTitle": "Ignore rotation lock", "settingsForceRotationDescription": "Rotate the screen even when auto rotation is disabled", + "settingsMapProviderTitle": "Map provider", "settingsAlbumTitle": "Album", "settingsAlbumDescription": "Customize albums", "settingsAlbumPageTitle": "Album settings", diff --git a/lib/l10n/untranslated-messages.txt b/lib/l10n/untranslated-messages.txt index 8e1232fa..a873507b 100644 --- a/lib/l10n/untranslated-messages.txt +++ b/lib/l10n/untranslated-messages.txt @@ -8,6 +8,7 @@ "settingsShareFolderDialogDescription", "settingsShareFolderPickerDescription", "settingsServerAppSectionTitle", + "settingsMapProviderTitle", "settingsAlbumTitle", "settingsAlbumDescription", "settingsAlbumPageTitle", @@ -59,6 +60,7 @@ "settingsShareFolderDialogDescription", "settingsShareFolderPickerDescription", "settingsServerAppSectionTitle", + "settingsMapProviderTitle", "settingsAlbumTitle", "settingsAlbumDescription", "settingsAlbumPageTitle", @@ -132,6 +134,7 @@ "settingsScreenBrightnessDescription", "settingsForceRotationTitle", "settingsForceRotationDescription", + "settingsMapProviderTitle", "settingsAlbumTitle", "settingsAlbumDescription", "settingsAlbumPageTitle", @@ -235,6 +238,10 @@ "defaultButtonLabel" ], + "es": [ + "settingsMapProviderTitle" + ], + "fr": [ "collectionsTooltip", "settingsAccountTitle", @@ -252,6 +259,7 @@ "settingsScreenBrightnessDescription", "settingsForceRotationTitle", "settingsForceRotationDescription", + "settingsMapProviderTitle", "settingsAlbumTitle", "settingsAlbumDescription", "settingsAlbumPageTitle", @@ -344,6 +352,7 @@ "settingsShareFolderDialogDescription", "settingsShareFolderPickerDescription", "settingsServerAppSectionTitle", + "settingsMapProviderTitle", "settingsAlbumTitle", "settingsAlbumDescription", "settingsAlbumPageTitle", diff --git a/lib/mobile/gps_map.dart b/lib/mobile/google_gps_map.dart similarity index 90% rename from lib/mobile/gps_map.dart rename to lib/mobile/google_gps_map.dart index 5415f832..9809111b 100644 --- a/lib/mobile/gps_map.dart +++ b/lib/mobile/google_gps_map.dart @@ -2,8 +2,8 @@ import 'package:flutter/widgets.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:tuple/tuple.dart'; -class GpsMap extends StatelessWidget { - const GpsMap({ +class GoogleGpsMap extends StatelessWidget { + const GoogleGpsMap({ Key? key, required this.center, required this.zoom, @@ -41,7 +41,6 @@ class GpsMap extends StatelessWidget { ); } - /// A pair of latitude and longitude coordinates, stored as degrees final Tuple2<double, double> center; final double zoom; final VoidCallback? onTap; diff --git a/lib/mobile/platform.dart b/lib/mobile/platform.dart index 394ce6a2..29cf634f 100644 --- a/lib/mobile/platform.dart +++ b/lib/mobile/platform.dart @@ -1,5 +1,5 @@ export 'db_util.dart'; export 'download.dart'; export 'file_saver.dart'; -export 'gps_map.dart'; +export 'google_gps_map.dart'; export 'universal_storage.dart'; diff --git a/lib/pref.dart b/lib/pref.dart index 2a2b8780..abe63b6e 100644 --- a/lib/pref.dart +++ b/lib/pref.dart @@ -133,6 +133,11 @@ class Pref { Future<bool> setNewSharedAlbum(bool value) => provider.setBool(PrefKey.newSharedAlbum, value); + int? getGpsMapProvider() => provider.getInt(PrefKey.gpsMapProvider); + int getGpsMapProviderOr(int def) => getGpsMapProvider() ?? def; + Future<bool> setGpsMapProvider(int value) => + provider.setInt(PrefKey.gpsMapProvider, value); + bool? isLabEnableSharedAlbum() => provider.getBool(PrefKey.labEnableSharedAlbum); bool isLabEnableSharedAlbumOr(bool def) => isLabEnableSharedAlbum() ?? def; @@ -308,6 +313,7 @@ enum PrefKey { isSlideshowShuffle, isSlideshowRepeat, isAlbumBrowserShowDate, + gpsMapProvider, } extension on PrefKey { @@ -353,6 +359,8 @@ extension on PrefKey { return "isSlideshowRepeat"; case PrefKey.isAlbumBrowserShowDate: return "isAlbumBrowserShowDate"; + case PrefKey.gpsMapProvider: + return "gpsMapProvider"; } } } diff --git a/lib/web/gps_map.dart b/lib/web/google_gps_map.dart similarity index 78% rename from lib/web/gps_map.dart rename to lib/web/google_gps_map.dart index 4b4fb0bb..5248dc6e 100644 --- a/lib/web/gps_map.dart +++ b/lib/web/google_gps_map.dart @@ -6,8 +6,8 @@ import 'package:/nc_photos/mobile/ui_hack.dart' if (dart.library.html) 'dart:ui' import 'package:flutter/widgets.dart'; import 'package:tuple/tuple.dart'; -class GpsMap extends StatefulWidget { - const GpsMap({ +class GoogleGpsMap extends StatefulWidget { + const GoogleGpsMap({ Key? key, required this.center, required this.zoom, @@ -15,15 +15,14 @@ class GpsMap extends StatefulWidget { }) : super(key: key); @override - createState() => _GpsMapState(); + createState() => _GoogleGpsMapState(); - /// A pair of latitude and longitude coordinates, stored as degrees final Tuple2<double, double> center; final double zoom; final void Function()? onTap; } -class _GpsMapState extends State<GpsMap> { +class _GoogleGpsMapState extends State<GoogleGpsMap> { @override initState() { super.initState(); @@ -45,5 +44,5 @@ class _GpsMapState extends State<GpsMap> { static const _apiKey = ""; String get viewType => - "mapIframe(${widget.center.item1},${widget.center.item2})"; + "googleMapIframe(${widget.center.item1},${widget.center.item2})"; } diff --git a/lib/web/platform.dart b/lib/web/platform.dart index 394ce6a2..29cf634f 100644 --- a/lib/web/platform.dart +++ b/lib/web/platform.dart @@ -1,5 +1,5 @@ export 'db_util.dart'; export 'download.dart'; export 'file_saver.dart'; -export 'gps_map.dart'; +export 'google_gps_map.dart'; export 'universal_storage.dart'; diff --git a/lib/widget/gps_map.dart b/lib/widget/gps_map.dart new file mode 100644 index 00000000..1bfc570d --- /dev/null +++ b/lib/widget/gps_map.dart @@ -0,0 +1,124 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:nc_photos/mobile/platform.dart' + if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform; +import 'package:nc_photos/pref.dart'; +import 'package:tuple/tuple.dart'; +import 'package:url_launcher/url_launcher.dart'; + +enum GpsMapProvider { + // the order must not be changed + google, + osm, +} + +extension GpsMapProviderExtension on GpsMapProvider { + String toUserString() { + switch (this) { + case GpsMapProvider.google: + return "Google Maps"; + + case GpsMapProvider.osm: + return "OpenStreetMap"; + } + } +} + +class GpsMap extends StatelessWidget { + const GpsMap({ + Key? key, + required this.center, + required this.zoom, + this.onTap, + }) : super(key: key); + + @override + build(BuildContext context) { + if (GpsMapProvider.values[Pref().getGpsMapProviderOr(0)] == + GpsMapProvider.osm) { + return _OsmGpsMap( + center: center, + zoom: zoom, + onTap: onTap, + ); + } else { + return _GoogleGpsMap( + center: center, + zoom: zoom, + onTap: onTap, + ); + } + } + + /// A pair of latitude and longitude coordinates, stored as degrees + final Tuple2<double, double> center; + final double zoom; + final void Function()? onTap; +} + +typedef _GoogleGpsMap = platform.GoogleGpsMap; + +class _OsmGpsMap extends StatelessWidget { + const _OsmGpsMap({ + Key? key, + required this.center, + required this.zoom, + this.onTap, + }) : super(key: key); + + @override + build(BuildContext context) { + const double pinSize = 48; + final centerLl = LatLng(center.item1, center.item2); + return GestureDetector( + onTap: () { + launch( + "https://www.openstreetmap.org/?mlat=${center.item1}&mlon=${center.item2}#map=${zoom.toInt()}/${center.item1}/${center.item2}"); + }, + behavior: HitTestBehavior.opaque, + // IgnorePointer is needed to prevent FlutterMap absorbing all pointer + // events + child: IgnorePointer( + child: FlutterMap( + options: MapOptions( + center: centerLl, + zoom: zoom, + allowPanning: false, + enableScrollWheel: false, + interactiveFlags: InteractiveFlag.none, + ), + layers: [ + TileLayerOptions( + urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png", + attributionBuilder: (_) { + return const Text( + "© OpenStreetMap contributors", + style: TextStyle(color: Colors.black), + ); + }, + ), + MarkerLayerOptions( + markers: [ + Marker( + width: pinSize, + height: pinSize, + point: centerLl, + anchorPos: AnchorPos.align(AnchorAlign.top), + builder: (context) => const Image( + image: AssetImage("gps_map_pin.png"), + ), + ), + ], + ), + ], + ), + ), + ); + } + + final Tuple2<double, double> center; + final double zoom; + final void Function()? onTap; +} diff --git a/lib/widget/settings.dart b/lib/widget/settings.dart index 46dd5b69..3bdc01f7 100644 --- a/lib/widget/settings.dart +++ b/lib/widget/settings.dart @@ -17,6 +17,7 @@ import 'package:nc_photos/pref.dart'; import 'package:nc_photos/snack_bar_manager.dart'; import 'package:nc_photos/theme.dart'; import 'package:nc_photos/widget/fancy_option_picker.dart'; +import 'package:nc_photos/widget/gps_map.dart'; import 'package:nc_photos/widget/home.dart'; import 'package:nc_photos/widget/root_picker.dart'; import 'package:nc_photos/widget/share_folder_picker.dart'; @@ -105,17 +106,16 @@ class _SettingsState extends State<Settings> { label: L10n.global().settingsAccountTitle, builder: () => AccountSettingsWidget(account: widget.account), ), - if (platform_k.isMobile) - _buildSubSettings( - context, - leading: Icon( - Icons.view_carousel_outlined, - color: AppTheme.getUnfocusedIconColor(context), - ), - label: L10n.global().settingsViewerTitle, - description: L10n.global().settingsViewerDescription, - builder: () => _ViewerSettings(), + _buildSubSettings( + context, + leading: Icon( + Icons.view_carousel_outlined, + color: AppTheme.getUnfocusedIconColor(context), ), + label: L10n.global().settingsViewerTitle, + description: L10n.global().settingsViewerDescription, + builder: () => _ViewerSettings(), + ), _buildSubSettings( context, leading: Icon( @@ -715,6 +715,7 @@ class _ViewerSettingsState extends State<_ViewerSettings> { super.initState(); _screenBrightness = Pref().getViewerScreenBrightnessOr(-1); _isForceRotation = Pref().isViewerForceRotationOr(false); + _gpsMapProvider = GpsMapProvider.values[Pref().getGpsMapProviderOr(0)]; } @override @@ -738,19 +739,27 @@ class _ViewerSettingsState extends State<_ViewerSettings> { SliverList( delegate: SliverChildListDelegate( [ - SwitchListTile( - title: Text(L10n.global().settingsScreenBrightnessTitle), - subtitle: - Text(L10n.global().settingsScreenBrightnessDescription), - value: _screenBrightness >= 0, - onChanged: (value) => - _onScreenBrightnessChanged(context, value), - ), - SwitchListTile( - title: Text(L10n.global().settingsForceRotationTitle), - subtitle: Text(L10n.global().settingsForceRotationDescription), - value: _isForceRotation, - onChanged: (value) => _onForceRotationChanged(value), + if (platform_k.isMobile) + SwitchListTile( + title: Text(L10n.global().settingsScreenBrightnessTitle), + subtitle: + Text(L10n.global().settingsScreenBrightnessDescription), + value: _screenBrightness >= 0, + onChanged: (value) => + _onScreenBrightnessChanged(context, value), + ), + if (platform_k.isMobile) + SwitchListTile( + title: Text(L10n.global().settingsForceRotationTitle), + subtitle: + Text(L10n.global().settingsForceRotationDescription), + value: _isForceRotation, + onChanged: (value) => _onForceRotationChanged(value), + ), + ListTile( + title: Text(L10n.global().settingsMapProviderTitle), + subtitle: Text(_gpsMapProvider.toUserString()), + onTap: () => _onMapProviderTap(context), ), ], ), @@ -789,7 +798,8 @@ class _ViewerSettingsState extends State<_ViewerSettings> { onChangeEnd: (value) async { brightness = value; try { - await ScreenBrightness().setScreenBrightness(value); + await ScreenBrightness() + .setScreenBrightness(value); } catch (e, stackTrace) { _log.severe("Failed while setScreenBrightness", e, stackTrace); @@ -830,6 +840,44 @@ class _ViewerSettingsState extends State<_ViewerSettings> { void _onForceRotationChanged(bool value) => _setForceRotation(value); + Future<void> _onMapProviderTap(BuildContext context) async { + final oldValue = _gpsMapProvider; + final newValue = await showDialog<GpsMapProvider>( + context: context, + builder: (context) => FancyOptionPicker( + items: GpsMapProvider.values + .map((provider) => FancyOptionPickerItem( + label: provider.toUserString(), + isSelected: provider == oldValue, + onSelect: () { + _log.info( + "[_onMapProviderTap] Set map provider: ${provider.toUserString()}"); + Navigator.of(context).pop(provider); + }, + )) + .toList(), + ), + ); + if (newValue == null || newValue == oldValue) { + return; + } + setState(() { + _gpsMapProvider = newValue; + }); + try { + await Pref().setGpsMapProvider(newValue.index); + } catch (e, stackTrace) { + _log.severe("[_onMapProviderTap] Failed writing pref", e, stackTrace); + SnackBarManager().showSnackBar(SnackBar( + content: Text(L10n.global().writePreferenceFailureNotification), + duration: k.snackBarDurationNormal, + )); + setState(() { + _gpsMapProvider = oldValue; + }); + } + } + Future<void> _setScreenBrightness(int value) async { final oldValue = _screenBrightness; setState(() { @@ -866,6 +914,7 @@ class _ViewerSettingsState extends State<_ViewerSettings> { late int _screenBrightness; late bool _isForceRotation; + late GpsMapProvider _gpsMapProvider; static final _log = Logger("widget.settings._ViewerSettingsState"); } diff --git a/lib/widget/viewer_detail_pane.dart b/lib/widget/viewer_detail_pane.dart index 1b2681cf..2c71d859 100644 --- a/lib/widget/viewer_detail_pane.dart +++ b/lib/widget/viewer_detail_pane.dart @@ -23,8 +23,6 @@ import 'package:nc_photos/entity/share/data_source.dart'; import 'package:nc_photos/exception_util.dart' as exception_util; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/k.dart' as k; -import 'package:nc_photos/mobile/platform.dart' - if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform; import 'package:nc_photos/notified_action.dart'; import 'package:nc_photos/platform/features.dart' as features; import 'package:nc_photos/platform/k.dart' as platform_k; @@ -36,6 +34,7 @@ import 'package:nc_photos/use_case/remove_from_album.dart'; import 'package:nc_photos/use_case/update_album.dart'; import 'package:nc_photos/use_case/update_property.dart'; import 'package:nc_photos/widget/album_picker_dialog.dart'; +import 'package:nc_photos/widget/gps_map.dart'; import 'package:nc_photos/widget/photo_date_time_edit_dialog.dart'; import 'package:path/path.dart'; import 'package:tuple/tuple.dart'; @@ -248,7 +247,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> { if (features.isSupportMapView && _gps != null) SizedBox( height: 256, - child: platform.GpsMap( + child: GpsMap( center: _gps!, zoom: 16, onTap: _onMapTap, diff --git a/pubspec.lock b/pubspec.lock index ff36f0e5..b219cd09 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -309,6 +309,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_map: + dependency: "direct main" + description: + name: flutter_map + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -449,6 +456,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.1" + latlong2: + dependency: transitive + description: + name: latlong2 + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.1" lints: dependency: transitive description: @@ -456,6 +470,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + lists: + dependency: transitive + description: + name: lists + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" logging: dependency: "direct main" description: @@ -477,6 +498,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" + mgrs_dart: + dependency: transitive + description: + name: mgrs_dart + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" mime: dependency: transitive description: @@ -617,6 +645,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.0" + positioned_tap_detector_2: + dependency: transitive + description: + name: positioned_tap_detector_2 + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" process: dependency: transitive description: @@ -624,6 +659,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.4" + proj4dart: + dependency: transitive + description: + name: proj4dart + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" provider: dependency: transitive description: @@ -846,6 +888,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.0" + transparent_image: + dependency: transitive + description: + name: transparent_image + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" tuple: dependency: "direct main" description: @@ -860,6 +909,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + unicode: + dependency: transitive + description: + name: unicode + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1" url_launcher: dependency: "direct main" description: @@ -1013,6 +1069,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.10" + wkt_parser: + dependency: transitive + description: + name: wkt_parser + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" woozy_search: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 148e1ec3..1c3cb1f7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,6 +43,7 @@ dependencies: url: https://gitlab.com/nkming2/exifdart.git ref: 1.1.0 flutter_bloc: ^7.0.0 + flutter_map: ^0.14.0 flutter_staggered_grid_view: git: url: https://gitlab.com/nkming2/flutter_staggered_grid_view