From f7beb4067898876b7856fa8a8f608ef0075e1d05 Mon Sep 17 00:00:00 2001 From: DH Date: Sat, 1 Feb 2025 21:33:08 +0300 Subject: [PATCH] electron: Fix settings window create simple router to make svelte happy use vite to build electron stuff specify target to simplify locale initialization --- bun.lockb | Bin 242387 -> 242137 bytes package.json | 24 +++---- src-electron/src/api.ts | 10 +++ src-electron/src/main.ts | 107 +++++++++++++++++++++++++++-- src-electron/src/preload.ts | 12 ++++ src-electron/tsconfig.json | 3 + src-electron/tsconfig.preload.json | 12 ++++ src/components/Header.svelte | 26 +------ src/global.d.ts | 7 ++ src/helpers/window.ts | 17 +++++ src/i18n.ts | 2 +- src/routes/+page.svelte | 19 +++-- src/routes/settings/+page.svelte | 48 ++++++------- vite.config.js | 37 ++++++++-- 14 files changed, 240 insertions(+), 84 deletions(-) create mode 100644 src-electron/src/api.ts create mode 100644 src-electron/src/preload.ts create mode 100644 src-electron/tsconfig.preload.json create mode 100644 src/global.d.ts create mode 100644 src/helpers/window.ts diff --git a/bun.lockb b/bun.lockb index 4e248bdc6bfd2cea8c5afc489177e10ea2f8736a..251a9453660edf5cc7b4ddef9aea17a6733ab738 100755 GIT binary patch delta 40968 zcmeFad3;UR+y8yemXL#(RU%@nxiN%DOgZM7VxB^Sh#(|F5<^-fC^b}xU6zZf#q^hW*s+6|c=Y8$955B$i{@u^>x?jJ4o}TabbFOuL*0rW<&Aa==S6B0$ zxsq>IwaT5;*9FTq8Md|Hs?9~J6dKyDOZ5lK+*6HXJJuaPUp~wK{Z?CYIOG$b(Y;ig z2C;^vI2=jCVv2Tz6IMS0x#>S__Ivgdi7QFy6FLF5v0+0^$0?1#`h2NKP zpj6uTDEUy%BXc7^M~YE&Ok&bd3Yv*t6n%S6hr=IPGMB?q47mhdiyFt;(iKB)(92JB02$-tl)6$2<4M>%YM?lCNT4QIp7%3}_ zY0J3eAesM;O0{*yQ{kn6wdlUcG+Pe|(G~8O6de~O3{7rUR4QjunLbo>a*K7heV zKw6j(n=~+%+Ib4}HJv$&1%DB${V+335B+mU8JUmCrT{W#P~wod{?SRR>gwzt)iqn^ zESc7zzHZI1xTNS5s*&)jw2`&4fo@gGpxB|(@Eo?D4=JsvN;;WYR#UOR*if%LUm&Hp z1>rjVEL)Bm6c;lHySU`o(Xq&~ZmW7}>GugphQp#$1_cd?P5p=r#GNM_*{zKm8aFID zIr)8fY5nxZx?Pu%;-)P&pV~wh9FLUzVw-CFFr>J(Kr=19(Pe4KLNDg%lbp~gUlJNhOQNfpWMgE>oS@S@yK56f@*16?vql=A3O1ErBN^_E96Gp}+v5zH2 zCm|fm+v-y1BBgl~kutnfZGK?lu>P1ic1CFbC$`hI?v9iNsX%+Z05?Tvlm@4N03ihp zB?D<*zr@7&*yy2-gy@u*L6p3%gB}1q>dH7qG{ATuU;KynakZ&LKU zPP!R0I+?j$CDY=&=u$5uWp}NKl-ibIIh4Xqbk*i3;YII`EQ(y%O?Or^+rCM6-P+RV zGOBX)(3SeRv*z#H@gBSD=yY=N^v^KJOM;6K(pkesBn%VxlrayuO7-;WrHd^>NmhP6)0YvD zhUG+xVIJFX)MQ=VKht%uCB>#B(RN2{Qc{o{jedcb3Y~1E8+j95oF5a-{|3c6rkYv# zilw!gs;kuqDUJX8lHPBc&LwW>fcUt9gHlqbX#2rP>7t?2b-Eq4>;o_PbVW+(NpI>} z4+~0&rnen;(Is8S8CI>+(pwOa1j)(zAnw_`JQX>K|7GZ(Cv_poFg7{1e_V>=#!Own zFd4mMoH$GC(MWOAD&oa$wKB9EJYwh&%p3~70K9Xyl*=(YDK@%)(6Au`S3-z?W+7id zzGCXx@g1@#de66Y!Zt{0!D)CYAOb16XV;iOdaIx2>inEY@dW*nn8b?xA-XhpK-|#& zL3ugFHCCFKW;QNRD(zS5E9U)}=l$Z6`VV9|ib)xfTq;v%>sj?@&C&+rI&sAH9*ydv@1P=rAeRcd52_qsz2n20E%BWd-m@PR-I4N<gmmi zkQFrEj4K$L7PwrSdDe(>BXzMc@o^*Ku-r<#v}e9;XRx|Sbv(29*A==MDS8u_mMK)smApAqyazzpM3j=(*7wn*|FOOFKk1qHWr$<$a_Smy%Swj9|`EA`Fc-rOs+RUuzcJ?&S@LkdLujF>dnvs03GBYc=U5|1&94*N_ zhgoJ)sI#%@U)k*(Z$|RH$IRsWwt0r{7ft^vZf6%WlJ9wDCf{G1XZWsQ`d4*3Bh5&@ zkC~ZO-L4RxJhayNRSI>cnf@=iofpkWzF#ymUvj$!`8XVPh+|KT1WHq;IQ*O3uc*D#J3UviCE~GTWjD9K9 zH4rV>(z1g>otb82b+_}5naOtp^GtQOcQ}Kky?LQ}eeW5BBCOEaC!varEzPAo2^}ER z#DprcD>Y>iNrhk~*6~u~K&Ejycs~1`$D}9;D zq0R;787%I>NjVNF#}&l!Upm(?vnz+X;?T5xR{Jm?6zMl_=|yK5)4!hEyD#e@g;%cc ze8N~HQXX?9MrCDhu)@hch z6YA_?MmBJ}7QwZ(QpmWufhHBTMv-s15)Ma4GzXtRvtz}o=B$c7&V^=VL$~vhnaOue z^GrjxYdEt}8brRhakm*6?)JU|7ivZ|Zs5ffZD(F^TYhUDB zoKS1a?lz&8R;W&CPiWke&?iqq`O0`=yXjEV23}97@1KOKm1QxqYGMVXChtE9$+5hJ zRaOf^&CEqj8hGgdW?wuB6?)N%gzM%BIoFt(&D`D}^Dw2Cxu{uv?@|>Vjz}vsnvmwc zBGlR9DzJn_S)qx9;;hh*grcobL}gFxT0#RYt{?+0)(VXz)W-^)d=je7QmOOHAf#h| zBBX23>LrJxyQFZfCnTNZZAOQNx~`)ITOA!ux4#(VaJbQOnAu^WE?)+7H?*AAQZyW` z8Jg1?Zu`(=c38`z>mFJ=G%txW8do=ab_#dBR^8#K0m<+t>vd?2(X0{e`Vmbs%W17r zH85jePtR{gzZvGNVa{(G?vuABr(`%)=2aLOZ%L+qgxlCy)9e`$?tPEw+U6pbs@hba zX;G=Z&qzYjvL{Kr--W4RMpdov`j$`!;;3Ozm`^QTx~}|4v~Z%d_MWZfG_y_1u#T0A zIqV%wgBzHERqDHjN=WDSewYtR6BOFnBg|RboZlhb6&~W5KiSN`(P*`0=DM~Ml7zWr zhPY&*7cbzGilMFuG?{b6O$zmX1FeC1fixf4JoB7c6=EFfey#TI}xhSZ<@k5w7ze_kSJ=4W)B-S;HcMW%KtE=n5 zZ0{51MIBmOKI=kAmI)j)*P_GBs802boAu0|-NKCy_09R+!d+SQb!lE^G>h0NG)9!& z=M`wGc$W2`Yp81&n$(NI6%y)N`6Mp7YN+cwH1VOAwQ^K2BYU`w^oHjA9^tNE8gh-Y zG7%@WB)^tcCM5G-i56}~(IekU2p;FrQ*9W;!7@5rV1biZfI0W1~R4YMC)ed zEX~WuBoZh1SdDFKYxE2rR%qg3`j|Ygph=$e3=_Q+6_@(?SbIk#n#AQYqa(w7Y$c}^ zbplNaw}zdo)XTb&4r>y}ph@Al16O6)8tFKATtbrqtnT%Fkq%_~raK+nomd>K?Znj; zmSu!0MRy8yO|&%{&E|FhO*fkAI{nPdes1rUt>_GMQN{YMbO~9xi|tOdo>o3I)LF>P zjB&e~v6t#$DQ+5u#)wZZtMf*a)Qk}7?bk+^q{qZCG@6Vn$jjK*#w;Ei?#k6xFMYXW zU31nqGh^MZjd0qZRNm(YH0k{(3z4fDM>Sa>bsvsFv%Oy@)O8q5)=3uD&0$_B%sx&S zuVOF$v^G=MPP86cn;quUUhmbUpf87_$4W%HEyKWokU0`oc~yF+-Q0R${s)B zi6-mKKC}*I;H3Jl{A~44I?L4xP3p?nrL0M4GM(tiwxO;aXxgpPWmoKU`m7n)=~=gS zwKYA$mZM2`T4!A2yH4i(A>rQTI!k{_1$q%;O=bAAP#7~in?2*hU9YnSP=IVkbkpx> z-E}=0g!y#kFo=Q!m|mG(&7KM2#)Yot{Dg4tlFW`!Gcc^at1BU~(hJpkGzOJD9ezQR z?jdu=M+b72?$bx9x6v3PGU@58VsrwY(j(b55KS!g>axz(aQ(YsK2MbFePKS4dh(I~ zI!lq(lW3f!h}$ z=|0vy6oDoUV~SGUIcRoYvH~ANlQqC{ly`+!=ml%24Im^|q^T0>z0~4mo4ZU%j~n|>;tlOjzkM1 zA&q7dZZtDTxjBWO;k$|HKichl&5Y!mE81wccZL2A$1CQd(e=G25b9}#&J*fkg=)t- z9Q~}&TteFJXF}Sp?Ep$O7o|4vBGAn;dqAjz6>2fi&cwBt5MxM&1zvx7kf)nutgb|} z=L{?MX|%ys#TjaHXB*>oy%DGF@qgt|pWSG6uz0e1c;AHyma~9&Ig)mhN#dMkW{!2c zst)lC7#X<9Xxb^!6T^H^WUN?Y(|O6v9OrhGh}UD;I+A%0Kx=31p6?NoBCP@7`T>1k3JZCG@f0EnVgllH4 zQKtyW)L@^82z3=r@%S&Rb(jx|^a4&!XA)0#dw&2^!@R)R>CY7N?BsCgPp1DHZtwOZ zWvyqTd1n&hM$)Ce>k=W(4(Ua$17hh>+9^KP;@b&L)&g4CA=EVits0u%VRxhHshT}A z%sI*|J~iCC=4fhV)pj5uT_riVEU`7+&TKU4Z59QFZqd|dMvZqXv`%IehtLItq%?0c zyHl9Yt9lW%uCYFy(4?=P^s{rWnK|9<{SCZ6oE3S^vxmqo)B#QG?d26shMwNbK0}j= z>dF{nbn`9EyEfWOGF+XBX66jH>mzi@NAGln#%c#}t$8Wby8{{{rcQm=6hhKGDn2>X z`yg5!Yt8$ekgR!5GrM7^D`cErH67M+GS2__0tBXZ$Ywx^+rX5_SW0+5xp6&*h z;p*nBS$?j!VJcy~$J{cjqU#Zw_P30y2I;!r^zIUmX8RjwEJfpxA%$>Gnlk>$Uc+=g zk0zs&V<68M{LIMNZdcz4dW_0FhSX?cp^u>F(d@l~6KvjzW>1dK-6rZR^|V-u){+F) z2I9JIYkD9we%;|{NSxlx#-VBN%IWq)TO+PgsCSV`c*b1Rt-h>Zb9m;2E)&O!b=^VJ zDP{GmHCbz{j9o*$C!jGVINt0h)Wk|7dy8S7nai`WH#}}5r8B{dRBpLcE1q=_qkBsn zT5<}TI%x}7N5%PQPjYgdM-%t5K(Qzkn5tdE5R5>{6KZK*Pz`*hKYQ>`MUzbR`SC+rW9(}| zjSrmBz=wd;QTr<$&5g!5?!-9^E!dj0ju|>*Yo2)bM&p{x@n|U_JrZRITtt&jcUenB zzPGeyowJe`DYLspkoWbTt;K-ulk#3|OJFxNCRy+CE*%%f=16)c3z-aN|V zOj+jIqUmmu7R<3VJubdNd)n4K^E^u+M|PjaXu;(9)KAGUQUm6EKRkmLhDJ_rg!){w zwWroWna{RmIGQYCd93TeS~Q)LlvH%So;Xj_c8BSJHH#wCWfhvVKo5tjXx-2(A9=?w zkiCnup7Vt1zsBtGSv%M@kP4ndN1gOX1kLo z9m~x#Yu&C(aP_cfUB{_I7VC_u5*CNd%yn*;Yl-e`3Zv-uX!dG=mVstFYg?EX3J>%q z)OVFy>bXEMg1m>IwG-ZZ7om77R6fgUAKYw0_2i!E{W&2XQo{MYW1R}gDUFa!E~>{V z;i!3LquY4=j#+$DxU1$e&n%Cg6Uu*6$lT<1Er65ySQkp~uh4KJ*)&?NFRl22WBwkr zT38jZ7Wq49jnRsjSq!ooEA;TNt|QKVX5I7Ltp%EXO7QY(j~2Z*%m+m>(3^4a8p&9E@j4+M zEzyWS*XqXUuBx+6+v~>>aa3{2Q3rz>9#@a@S)*diP?j_UZVpcBrmvffSbygcM8O zY14B* zh$hZr9l{ZN(IihRo%cO7YR_g>bDM6yKKmr1$?(^?uR`l$N~x+Mt*q3FxQ_hkmhta91L>#&y@};VSPmA0N7ifXJs*% z<2L`lAk(a@{ueU(ALmmD%Wv%le9QX~*5@hle_6N7w`%kPWj_Q4_)XX2KcpAjpEmzI zDd`;ar`UNRr3-UO|Nc!1<-?aqbMx6EWyB!2X#XIc=FzjoIM6Qow3Ibo3fhU~oiIsO z*iQSb^oIAdd65$I=SwOXVCyA>wC8~}sLv6d~$(-0VwBtoe{%&V|zO8_EZxcJCrnaF-2{yC!XQg3AoiAqj z?`7MnrEMirvTtqcBBl5aNU3&bq(pU*FIx)V-PWI#LiONFWTYK0QtV%G@|;GvC_6%= zMD(@w|1VPfJ&^R0#UNY8iDE`wD3vC;4@Hyi8;O)=jj^r9iWQ${rNmFP`R7S-(qx0Isq7xxe6O(R`|M;QCAi<#MN04hUsC-;NO8^)A^(R`$~$JK`%P?5ck+pg5G>ddS7Hd zr2L{pJW^63|0go-zcG}$l(I7{YukyGidC@nXQfb;_!3!#FG*ij6kAHgs-a8zV5Cg7 zv@qL1qy+2PvVqNul%>2eQZj5}^CCr;UmFS4+~!3J-@?|PC&g1;h-VC?IeOWK&y!N) z-gdl5sd0a#6d*so5;?$*7b(F(w*EXR_Ho3!kV%#u{jUT6DJ3q2FG(;0Df%c|A8pH2 zA^C`uijJ|Rbg86Ex8t9cLQSxFOUn3{fFzh`%h!>T;TyK0NQs|OA&)E4qD<%G{ZGYa5N2XZ?U$hC4VtC1x zmu>!8Db%+%FH-EUAceYW^Uq3&{~lhZ#!aN?KiYOb8UY-MApWu=EGMFi%whUo)&B7k z*YbH*idTK$C8ykCjr8S9vd@Q<_(DjDFJj9Vkn(v}O1z)VKPx3YKT6cAuKYStG7hw5 zNjrf^;Y%SUqcS!xQuwmAENAo2lM+>dFG*hsDSA~~R?A_&`(+{PAXGzmJ|e}HAxJ5r zj?F(SWyfg6yGFL1NC`Hzb&)b=tiAhhQcT*44`ku)f+huawG)aIy&F;r>VcGs zMcMHpCD@lQab|y{6f_tq_VGwbpJ2mqZT z5!dvXnQgNoB{+vKX~rU?6u(5sze!o_R>PM?erDT!jug{l@?}e@_HkPmDYZI<6#jG$ zd0kcqEPq^(2y@Zb`aW>kPWInPsouA?-Lq1%zhW2j9a2oL@g?>*Z2kvZ-jql_&&bwR zb$+rVL`sHtk&?kZTi&^hDctd z==p6~$d*NslFtiU@1ETH@12{Qu3ml!=+FOkX_s$R;NLqpV^fA_Df#-Fl%?h0JGbQ) z>+UVn``Np;#E34g`}fW*-jKWZzjtnN#J_iL@xt@&>@2^su>5=H{`bzEB!@3PA|?3m zo%`QAw>1!+y=%(=5nXoKfA8Gl4Sr}ZN0Gltq5i#d>$|r2=HENFEUC}lwZ$u<%S`(J z$(=j$MwdY4oy*xqJa&{=B z=DbJ|Va1)kjeaY#`p7T2=KeS!&l#ii!s&nhIBDLlg^zAGDO$4IkneAlEmZE_?30P# zynJ@Vz_nYhxBhwc#2gd%HCnMIv%=ID=a(MWrmdP(+<8cKEkS5n_wV zst7T!0)%%Zh^?w)C5V<4A+`yzO*tz=JQO0fGQ_Nn17K@6%2aZ-o_s!R}s-%Ajaf*?LpCxkd8L`XG= zgKB&=h|xh1SB3ag)vOLtsT#zb>JW!jwh*U0 z32{u_72>)OU4tP`sH|X!c{L%tYe9UaI@W?{84R&ah?B}$8{(l5v9%#isVzdRt_4vv z1mcW}4uR-V8{(i4=TyNu5I!LgBkDk0PzQwADMa~Dh)ZfX@As=gbs$a(k*&&vLHLD2 zObUazqD}~LNQjWS%(bhYiH7w0v+}gsL%kAWhIFgvo9FS%*ZyiztonwvHOH5zFnjZ* znP>cut*xJD{-1B>A71X^>OU41o!=~Pu(>Pu)j1^|W*6U{a^k#72y^FS{nv2KW86|bq`)^LcTjUXPW=tdAd+zd=r?z94e^^%%H|FCt;jURi-J4{F*>aY6_7< zoe<)X5FyPVyw&(-5TlzyToodhs@WW(QZtA-%^_SWTZq#_G;aZsM`g5tn9>~Lz7W2u z@yiflEeNf686v;BE5vmny0(NUsIpo@%zGKayA?!X)v*;s%a#z^gea<Q)d%+d%lM=r#~NT0v3*jRb7||9YP#q9rrx4{MAWEs>5fFpgLYx$$ zj4IO(!Y=}1Qagxp>Vy!7ga~O5QC^L24>7tO#8n|Gs+t`jDz%50(*dHg$`<0Z5Y0P6 zR8<)rA*OVIxGzMIYTOATtRuvVP7u}AT_LUu(X}%~O_kLdVqPZ*?=BFvRL3q5EjvSO z6Cy-8yFxq^BDO1?8|qX|0_fb;U0_xOz|?iBpM~ks6=p9s&icyLjYK}(AQHMkG*r8U z*eOI{cL=wN>kcufJH$~T8Y}-E5Pm%%#`b_{styZrNQj_Fh~_Fa(%IeFLY)xtvZ~w@ z(Nc{U(Mp{`sM9?$ZrBUsHfm}w__iurM1-pQ3Zk9L5Yb-UK&b1lU>p&JaYvOI1u-uQ z;;|5&Rjb|*Eqg<3=nc_TJrd%f5K(;~x~nyP_*&fu!nZF(q>Ahd(W5WKULkrZS2ToA zG(!ysl1gP5w$2yt47hQlGItEs~wrVNL;CBzI>Hwhvv z31U$a#7uQVi0eW`BtvAV%w&jp$qopK&&1C z;X4u{Q$>!1=rIyvuMi8AYZQdfD2Rkn5R23@@o*4UW1tN8pIlPMu^iwG#mr5 zPE8#HF=Y(IEg?3jx?>^2#zHI_3$aPv5aPNJ5#u1XsLXK?^Tt6u7GkSvl?Kr=4PrwY z#5VOvh=)Q%r9-O4oq!e;_R!UTxDYL^f@g$SGo zu}{TKgcvjt;;0Y@l>h4xey>A}eI4Q>by$c)LIh2MIH*!5L5!XRaY2YrRprSLl_o>X zm<(}Poe|=+5DnjeIHIP$0Wswbh+9G&RduI8giV21GzH?Ax*^1MAtI(ioKTrlA?8hm zcr3(Ms?{`zmeU|MOoKS79trVKh^Xlhr_`G15UZy{_`V5oMn%2}(c?{sy+WK*t{D(M zGawRXKwMC}gxD!W;9C%vRNPw-gWiHTDnz#Op9$eN6JqR4h%4%_5Ql^angwxHrOtvF zJqzN35Z6@Y42Vh@5Hm6$Zm2UtoED1m`>THN9vmtH?aZA-TA;L_EMJB`@bwh~j zLPWd`aaU!&4KeR+h{rLQ3Kiy&?Z;j8K{ zh6r0sXwhPb{OX1f*M*2!0#Q(9E`gZ01mdv}g;lGi5G|KNY*-3WR6P>np%7775XID* zEQr-v5Wep~_^ZfwAbPw5u~&!yevkW3(8APDkCB#l40+&OSQgO>61}%p;DnuFO zzXHN<1;p4D5arZi2WmPlg=qKz#1J+01Lr`O=g){AR>QBc$!|X3e3QQxgAnLf|pO#@Kf|j-cOu9MK=WMzmX=7e>{Kr*|Po0Df!Gj z1@b8|Q5AjNWzz^5-v&S_+nkP3BEKOJ^@=N+soI}zzCZ8##ybFWI!uG*F$t^LjNPwv|( z){AuM#e;TyaNcP+*?bOMaF%kO+mU_2dCAGC>cAyub=-gVk~6@|_mj8uAGSP&^pmEg zS=lJ7X=!sPSIAWs8CahmnH8nJ9guWey7ZCfFBMw-J>8kP6kCl=g zj-L`#fd@tr)qQ|bMZG@2SlTelezaT=1F@0!hu*fi!Zs(bAtu{gQJa(3pJPgH<=sH*tue%tmuDFWjse(-3!7VM`ER65 zV#gw>Dxa6_#NvVZHrLYTO2G|>llPQcS&6k*cH4GsY`ZeV2iaU(n=1>~7|18W=E@On zq8i812~DjC{(znxRUZ8|Vfl2hxeA1Tvbl~(304HZ+FWO(lv)Y2usM18SGdYR@|I6m zqy(#gPMS+|bhk-fmUBo((vy)k_Yz_GONR21mxm?8ARzC!N$a;^>5$kZ;+A#Mp+xaARyv-bR*SEijINjDmqSSDSEc+itL( zHUv)I6_n2qo2x@uem5YWc$*6)yhL7+lu?jilVODA2L&<;hT2?R!t3nBi8jY?#H@Gv zOCyKbTz$gzZM)$%#}CUKb>Ye&<-fp6G)uhvX&CF1mTZ&Zs4Z;L^Pgy0{2ldaiS)m` zA}xs<0dF|z|B*J=m~bw;#iMMl3EVWoGA2gbTvNht5|&RYlK%(G4+t%n$Uu3`Hf&B< zJR;l}o0G~(_c)X@-YAzQV@ZaLyoxPsD&CM=%}q`Y_71uV9?xt1NHyDQ`Zn^YEQ{e;%B(B|gZ zocyPdrK)2BlijqV=G#$`M9Cat6SuOG_VfhO9&xB-C0s8cFK)_bk7eja-VR7DCq-5P6d~9?2^>-$FEaWyw`K-4M2N0GPOYJw<+(5z|;iRG);Uvi* z(8=aD+jenq@)C7l z3C@D^;2e-&+sH3+ zTm|2Oo8T7s8QcZ;z#Z@a`~rRj*T8kK0jvXS)#G7CF>iT=d7TOzZWIfAm!RzNvZrqc zyTER+2kcWFhclQD68sb#06RZ!Jk0R z7Og=9Xb0q6(E-R=;te221^ETSOCSiytKbiS>~ZqCxcqnV%OD#Z0VAasN8uznJEVfw zfV}Kkg#>bTs0$haIRLtW922Gic^7{%kR!rakPgO!*FY1}*Fe^mFc<>lIIsdf3&=4* zcJmE@=LQUZ0xQ9Gumi|10OfkP7u3U11(3Xitr9d{>EMS7!AQij@MuDc%64^Gdg6{!8 zv9NxQAwPP39bCZZEI0=Wp_c@*eadzzyQ3TX+#nCg3*N`>Q}6{i3=V*!;0V|RHiPXz zHn`;=O%6h1!Dw)s4DNuNU=o>625$g=^Z-x*6a?AWehV&w9YD5S*=Ezg55)8KuVWf0 zLAVeo46YFO9k>K`f;FIQ4#z<2cSprAC<01DCXjFlkXzvnTpokGfxHb$f_B(-1arVV zkOD@50YEN5!@zzp7?cBLK~bmLILhdkcAxw^gU_&?37-KX!3^}NKz?R34y1u#&b%7j&D^w8pL;s1M{6EGI)b&nL(a(xM6U0bN0N@COE8gRj7G zAjeMmd2&7C8Us0Uz78gW37{)+-GH1$LeLYya>C1O$WMtS91dClIikJ{Bs^FKyBsfX zkg)=DKnmzgWPjuUAVEbllQ^kN zX_<0-jHOepQ&g*9^dL|c1OPu!49J-#2J{26p2!Sq2AY66Kn^K#sOc%0f$KX`Up2ZL zKHUia#YcTT#<<*EjxOH=Iqob5Vm%w|1Y5xxFaxXx?*KVEF9nOhLa+d2s7GUs>S>a6 zK9~n23(@C*w}A=f0tGUG6tx6o0kK;SmVp&uC0GUC1?z!zqC!gXl5P`_lh#HcHk-i~ z=7E)o7|2ZA4kY1wKnZ8txV6IpH` zTX9Yx=UfBn4RV0{=)ZuU!96=pPH&G0KLo#m2jF+`8~6)627gGe{7FFIAb~{62~P@^ zZ7Uz}1#%1&DW|BV`Fl zrlo;wNs@61P|6OMLzV|G+Oh(&5(ok>0jaFyQ4`bvQcx`r3~B=@v>|8!Bo`oJt4ifJK}oGuiND<9vaf5|FZx6(M{MITj2B zW58=bW=1knHp@gX99)KzS&&3n;z!!N%!m}iBfuz-3P#Hyc$L6%unb5o#d+_5EFe>1 zDUcm=26z+5aDN>+4on0Sfb^A2&GE=|kOpMR$`loTI{Gy52AB$_fJtDo7z#PrmQuI^ zQjxd8Y#^CrAZLM@;4L8WB2A!M^7Ll55N-jOXUk0FH1e2_TnrWgX@nr{nZB@AD;JSx z!D%3Uv>L1gD}blvvWTrhKLtJnQuza5KiCKMfcL>R@E&*GuFcY*C-2iOUO-wk}g2VgIdE|W${rN08YOX&ZP zQ6z!X{sfSIIS!=eM}gG*bMO(6+Dku5nuDM`I0D4ohrp-c6L1*FlKvS|Y$|{+z%d|R z{1W*!_(uBwB#;U`o7ow3$xQYJUq*jnPzdA)F5nHs3)O+lxxbK)!FS*a$Oad|c_2Hk z6e@%B0=Nuh99#lv-}3bbkd5GX4TBODp~aSwO-fC4)g=An>AfIe-%wHhhp`E3NJia*7Vb zQ!ES)E-%Oj4q6=jUl7GpZ~?-Sp(GG47RYFpu*{4+pa94X@`Ic} zw#1^OOCao7w2IrhKT;YbX(V34GJ8DnS!oa@Fp`=}A!U%IK_HMmE(J;gsg%?>9}w^4 z1)faG5ij?6NiUCrq|%Z{Merh!MXCbQjg-ZxJmGZ0Qg+(c5S~>^3Xn`Bu?!f=s4C%X zq*PD}sSJvs%gN>?!k$W0v*VwwM0L1lD^e4^2B-zZ8w~0+YbBGTmLwGS3q zap_mb8GGtd;s4P7od4ZvvP>mlodMz)k$6Hd4xkfWa)Sq`ox z@@2V8v<7WJN6-PZ1rb2FcA!1z1SA8AmpI{ND#{H^c6_;obpvwg=?UZlln3+%sT9^9 z83Ux-q>}vzM}xG!eDwkHv`qR$Tr6&quxBcXE}r;%{Ij;thQ;oAUE%2h@wj;T_*5eo zg6VNzZJ%aT+40>pqnlBz2*cC!Z-V(ad)KHIT(?>c$7FSPfl(x9FhR#0)p3U5AFzRZ zIMb$|J~trvuj4o78P47z)hvS#)Dkg}71M=*>yNFcwmn|;I|f8otHrTVeKo_V6(G~Y z7lRMe+GQtR+TB|WtQt9LsxogGwRj1k>sv-umvl)!>}IO$4-9|ja`n52eJcMf;|2BA zTSlPsb9MJEsPn3z#C)&H&ol-)e^F%?7%!BhJVy>%Nd|oemKb|&)Z$GPREwI>mICU) zOj49k=R`c4vuKG641d*RmQkGd0i$MNuw7jeQBq}yundX?)^>RQz4Yuqk8Z3~+gDss z6Iaw^U(^Y-WsVw--l}j0Rhy)0&L)E;Dow;TwJC$v+GIWT_=#34!1FJqPwsMJ`Tk=Q z4jRrH)k3O;&?YN!gfm5DEHVnK%d?G~0iJ)AJZ@Km)wOdbeD8&E&AQcU20P{{r%6d` zRRAKu^RJrMY5V#1tl96q`qb_V)gFV8?7U2C9QMwdaf5IBl>hRnf#)AepW?NCP@jVJ zMn8?orJ@&8k)G9dFGwyqv_FihRCS*>HALz~y4r z@jgAr+E4ohzdmTNHB*ACF&TbP)hW+YhE-x!_0~M2fn8pJ=U#LqzmULpsyRTSNi&4$3!J3{FDD_tFETBj1%G-^!)+~R&loD*{41sHvN_3u; zskRic>!5rV8h^Tu5-TJ9vdX`RdjF^@FQQKes_f+k&EgoZeqRo6%`$)IWVKGLtl3mJ zS8z?4h-=j)xRB?~DQ)nDJ(+4Wncrte&isr57F8>0whCH|6P`Dxw1G9J{GG+sYuNE( zA9Kf3Y!kH!F64PLNT(faPmn5wD%EmMzmoN|*m3Hy6#Kjxq?1}R$lv+CYO{o5t(oE} z_Nq#Q3whpr(P;~^Qon#h;?av7!7$(U z*N;EvF8*10FK6v)!L?;+E?Qo7SZer%)Glv5vrW&L@@4<{FYe(!k3}b9N|APJd9SD% z*C!Qz8Z%riBJ+S*7?j0e`pm}*ca$sm!&8HI)d>uEH~6Mh;vROTu?wxZAuRa!<1L=r z6|SI4XHkjJ3c3om0B3G*~*%*wzg`w z(rC+ztP57suj`qfl4HYr`?q{nAY>4Rq1y205OsVd{o1UKc6ycSE&q7ftB5!~RG$nU z6C*93-v8|_d(Iwa>9S5Qw2${VSK&fag|4DSX=(_<_##v-T}5La*HO1u(U_TZ3-dnx zja-!%M=X1H70Ib#wYnUY!&KSTMtX_=+DGHW^%StGuKHlL;YTN(T20oE>Z-hJ48MR7 zS|jJFu6=*}>$h3a53Cwlr;HHgUh}k5m*nJO9Cize?)ahjq&-8hom^AQ#@2qzVIB|iRj=Rz!Sf%MZC#E5VG3l)m*QZE13 zc3S%XVnbDJ9q#k|qre@;#qT-4W$St@?0#7guKKNGERL0%2|Jg@HsETw34)Rv*H_&Nes?;IQwh#rH=`r5Zx$s7HWoz`6axPfjs(_CkMqQ~0ft$tZ@)o_lJ zQOx{1+*Fm`=y8d)Q|e|r3-B7aRY7q=z;g<(OK;%Qf@-(eSqJ1|>c@>n9lh%oQK6fR zn*4kqZj(`li9CIiF<#!{&9~X`Gu~^hDs49A2Rv%6dwG6`6F>L-Vy+BUG8O+A>cVES z&8vRh%+%@8M!mGf7*Ha*jqdy54Y%dJF>H1?_A;F4`|WMi#w|v0iJ@(^m%b=)@BMF^ zM(Z`DhO{)bt@>jNzLJ=>&sWL_tAd@H`2(Mf&q zA+`LVv!2J%-(-K8b4+$eEM*>G`B`VxXgd~Hv5;}u_N5A2msKbeY&gGxk-778XZ02q zPKO%u9=%(ji=G4H7hG09SGg!RJaI`ac2l(kgE}=aC``Hw-=44D_I?d(f6-+%vtxXR zztyz(l{X)fRCXw8(Y=eh{T{W5$3i^vaQ*q$CxnDeu`TGclU-EVZS>hc=YF}18is{& zqN`et3|QDrSF}cs87Ud@(ducNo2a|n7$_IJtIIoZlI?;z*Sl*M-1c&;|MYhEjZX`| zPmE0K65UQMUU8~wQDS75qLXds1mx(UJNd8L!`ro7_d@|J?8)0i9oTO88@8ePWjnWn zGOF?pBO<`7m+rrW$|d`)eY;-rrljRVU8SX>n=7eonHyhOZtiP zj^!UWrL8L9Oo-Mlps!23&o=p>pFXPf&U)$QJLm31c{yciphk`&s{Q+%X{yEO3qf%1 zdzXujdW#dA$Dj={a#Ra=bT@ta=l9?OwcBXUZ+PPN7-f{t9-|OH;tbeBOcT|94+T}}%71$UeD-O~f856Y-!%`X`R}LF z->C8Xt)}xxrkMJCKRdz=mE(ZXy!~&3c{YnXlSjtJr^NEOdv5l?dNbzw6>vIR={^@=O-vg^0e1)Kpx^puZ7%A!0b<3P_``%80z?WNQKWAA^zVh)p)GJdEYqE$lA z<$N#K?|pENOm&>Ynkp8aH8tS5`?cl9SatV98s%1bexTQSsuS5!N3`p&j3s?jvYqx^2(IDqoE#cpA&r{ZJ8AK+FGttK!rqHo z5F@9wA5$v5T6cQ+2x8<|Mx8sUsE-+%*>=*#ecUg5ty^%%PKtqby74#I+1GPADe;`s zfxV1Ti_3C;*_EVg;h6Bj>O(D(J|QdH;-3rAr-YD?NGjE=H(+hDS+Tb~@sI{ki|uUH za)3KfsQ&#vZD-3ZN1V>!oupnn$O^~-aPvXdbaMp%Q3k`ZMXUb4WnH63hEF(5SC|#* z@j=eF`&FAy7*ghP41SSz?iQCmy+^GI+en%!hSb^bGBkh8C9 zeuRgo+s5cDc7OSOztzd_yJT)eC!SuVBV2o>9-vQP87oO4Hvg#YuXH)e&a zai6n}{_`2@q}uX1HTZ`k2luAyJO29I$l)w;GhO#(K*zHkuK%#Ig56B&c(Rcy`2|Dh z7c68TCwUL~{(7TXatx?Zt&W@^{v<~BpyLfAPYrn`g`LfFT+gG1e1Q-B$7=`7d4F%) z?Im38Yy*;3R7=Dl1cL(P5L|41g;#5i5f9m8thq}23cqw!x3F^#P)9`@rOF&bydBSZABX`{mJ0IIQ0Yz{HPu4P8j@?ezpgw#N#ii?B-E=$lSc8-X8L6ykWJ* z8Zv!UO{t#UsKHb8Ni3>&>pVf9j-6(=nvtU$6_Sd9wEE#{|9e@B`rXAq<_|ufN=!jw zDt++r{s~^SL!TzKJg_a`efvsR%J{Z-$J@8%Dj{nJNgJs}T#)LtnX2Sda@AJuPW_bkNzOS#r|WihS^4V5l4B~#3D~}K>`)0O@n4e4I!SZy zs@;fy7BjTD&(x;5E-ibf;nO;IRCi7qI_^XzGqvy-yo2l#+Ei0!D5GJu4ol zGk#W=FRdij&F~d9{w!5Etrj2xzQe94cJ(&3jk*@mI0ZYqzuTx|V%Jjzp8Id@w1I53 z`MzTuIaSAVcr1^agb4U>u6FQ)p>rn`$-S~1*~@L89%!t-61!LPVKp)wGL zer{4!ox5lRit^h<9&>b1L6`7SS@rTIZ8GK(Wo=M%F428^)Rjxzj{i(o11{65N3GTT z%SO6W-+=@2vXjalTcb_LmtErPz3lbG^}eb-#}NB8@}FlDMo{DLp2kg8H?t|Ir^@=) zsHNh+<=pbbK&XKDck~p9yXKQItkF9>7-f;AhozZ!zGYb)rG{TI7I?Z(JTJG=r@6?1 zD8Tc>)DB0FC!HP8@w8P{>-M@r&HN4*%~yffslbEpsK8cL@G2QwJGsBJoZ7%H%}Mzm z_v{zEsEuX4!1#5A`uux}w9gIKuk--(ix)(c!saw~{K_3L=c}CeA*2Ao> zH<&n)jO6>)g>jY=#VGhwXHIj10JlT}gVj^7H}CA`TU(_|#748}bJR zff%gv+qtJ_k*Uc~4gA;Ym`6=g)AG!Unf^4Uj+()FG@v&IrAb<7^o}tvx|c*fH5jK3 z$bnU#TLb=i+5C?aExzS2)>84>v^NhlGvurrqt=PAmcZib(oF`~J{9yM;;?${M`8}C zIX~jjFV$fY+3K;7_f)Z4%;f$m?G|LR+KLEBSZ~j=b}d%joS9wQnx57YJyJPulPXOG zAWB^9u2;fJcQ4*aF80$7?Ch10-tKUlX{?WxMP;l^Q4?=7z{)D`JNgM@mphy{_iWNj z&Fg<{Tl~9UQ98%75`3z%?od>Q+KmXfvso_yW4?<^omD0)!*JRQ220W%3_{v%(REoL za?t(Job7+v8PUx>h>`8$RMGRFw;lFZ=ch$vsfIs2H*ZfJZmHoI@Rt*&|71k`H$`Mo zge(d-`~8{{Gqd|dijbkn@mlAgD%@q%Z&Ho#(jE8J%)6A@Sm|nY>v*JHbb`Gsd+0 zjN+uP@K0TpjRAj#>i3@+0`?sGV~uKkk2$1O#+$6E>a%-1TY0X9@t+C)rh2l`_p#@U zUbXl>IqQL{e!OoK&)xSvmuNowAIR_D8}amAKB~h5qlR;-8vnp3l~z1Rce(nrR+IS6 zZ3;y>wMSb&JRI+RXIYoO$0v`7`F~cFSe(kR?Pvk_Y+uo$BUTXgw?nI!gs)bRJP+i9 zf~ZkEl<&WY$-Ub^z5tMa)G|KUzRc>n)t}b_3V;UFK9pOjo-24B z;RID6dAoH(!cpfH!BF{CnwJz5XYA424J^Pw9h4f!UZu}$RYE6$d@&&Z*92?EJmI%Z z_kny#Air@si+079#c@A?e2@c9?bMI7eYT&A16TloF3`P-94_>z*r!+k?Pd7CuHMyiHKW}=_PbT&4?LV2grKW4g zF!M~${mH~L{hcs#@bpe?X6ayTdh~Vmu?gz}(>QP;i(W~36;|n@)V!3`qST`8jv~xY zg{J%KGb>DYQ)lJ_9)ZFr!mKpCT%Eal`$`Sw9=7fI`piXw)0;Gy6}B@vGM^Qj{y>MB WeL9l{^MdL31DUzD-w0>^9R&bfTDY75 delta 41427 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 diff --git a/package.json b/package.json index 13cff84..f2c2578 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "tauri": "tauri", - "electron": "tsc -p src-electron && electron build/main.js", + "electron": "electron build/main.js", "start": "electron-forge start", "package": "electron-forge package", "make": "electron-forge make" @@ -20,17 +20,26 @@ "dependencies": { "@tauri-apps/api": "^2.2.0", "@tauri-apps/plugin-shell": "^2.2.0", - "electron-serve": "^2.1.1", "svelte-hero-icons": "^5.2.0", "svelte-i18n": "^4.0.1" }, "devDependencies": { + "@electron-forge/cli": "^7.6.1", + "@electron-forge/maker-deb": "^7.6.1", + "@electron-forge/maker-rpm": "^7.6.1", + "@electron-forge/maker-squirrel": "^7.6.1", + "@electron-forge/maker-zip": "^7.6.1", + "@electron-forge/plugin-auto-unpack-natives": "^7.6.1", + "@electron-forge/plugin-fuses": "^7.6.1", + "@electron/fuses": "^1.8.0", "@sveltejs/adapter-static": "^3.0.8", "@sveltejs/kit": "^2.16.1", "@sveltejs/vite-plugin-svelte": "^4.0.4", "@tauri-apps/cli": "^2.2.7", "@types/node": "^22.13.0", "autoprefixer": "^10.4.20", + "electron": "34.0.2", + "electron-squirrel-startup": "^1.0.1", "postcss": "^8.5.1", "svelte": "^5.19.6", "svelte-check": "^4.1.4", @@ -38,15 +47,6 @@ "tslib": "^2.8.1", "typescript": "^5.7.3", "vite": "^5.4.14", - "electron": "34.0.2", - "@electron-forge/cli": "^7.6.1", - "@electron-forge/maker-deb": "^7.6.1", - "@electron-forge/maker-rpm": "^7.6.1", - "@electron-forge/maker-squirrel": "^7.6.1", - "@electron-forge/maker-zip": "^7.6.1", - "@electron-forge/plugin-auto-unpack-natives": "^7.6.1", - "@electron-forge/plugin-fuses": "^7.6.1", - "@electron/fuses": "^1.8.0", - "electron-squirrel-startup": "^1.0.1" + "vite-plugin-electron": "^0.29.0" } } \ No newline at end of file diff --git a/src-electron/src/api.ts b/src-electron/src/api.ts new file mode 100644 index 0000000..edb04ed --- /dev/null +++ b/src-electron/src/api.ts @@ -0,0 +1,10 @@ +import { ipcRenderer } from 'electron' + +export const electronAPI = { + ipcRenderer: { + send: (channel: string, ...args: any[]) => { + ipcRenderer.send(channel, ...args) + } + } +} + diff --git a/src-electron/src/main.ts b/src-electron/src/main.ts index 57bb06a..d6d89f8 100644 --- a/src-electron/src/main.ts +++ b/src-electron/src/main.ts @@ -1,11 +1,103 @@ -import { app, BrowserWindow } from 'electron'; +import { app, net, protocol, session, BrowserWindow, ipcMain } from 'electron'; import { getSetting, loadSettings, saveSettings, setSetting } from './settings.js'; -import serve from 'electron-serve'; - -const serveUrl = serve({ directory: '.' }); +import { rootPath } from './locations.js'; +import { PathLike } from 'fs'; +import path from 'path'; +import fs from 'fs/promises'; +import url from 'url'; await loadSettings(); +function setupElectron() { + const directory = rootPath; + + protocol.registerSchemesAsPrivileged([ + { + scheme: 'app', + privileges: { + standard: true, + secure: true, + allowServiceWorkers: true, + supportFetchAPI: true, + }, + }, + ]); + + const fixPath = async (loc: PathLike) => { + loc = loc.toString(); + if (loc.length === 0) { + return "index.html"; + } + + try { + const stat = await fs.stat(loc); + if (stat.isFile()) { + return loc; + } + + if (stat.isDirectory()) { + return fixPath(path.join(loc, "index.html")); + } + } catch { + const ext = path.extname(loc); + if (ext === ".html") { + return undefined; + } + + try { + if ((await fs.stat(loc + ".html")).isFile()) { + return loc + ".html"; + } + } catch { } + } + + return undefined; + } + + app.on('ready', () => { + session.defaultSession.protocol.handle('app', async (request) => { + const filePath = path.join(directory, decodeURIComponent(new URL(request.url).pathname)); + + const relativePath = path.relative(directory, filePath); + const isSafe = !relativePath.startsWith('..') && !path.isAbsolute(relativePath); + + if (!isSafe) { + return new Response('bad request', { + status: 400, + headers: { 'content-type': 'text/html' } + }); + } + + try { + const absolutePath = await fixPath(path.join(directory, relativePath)); + + if (absolutePath) { + return net.fetch(url.pathToFileURL(absolutePath).toString()); + } + } catch { } + + return new Response('Not Found', { + status: 404, + headers: { 'content-type': 'text/html' } + }); + }); + }); +} + +setupElectron(); + +ipcMain.on('window/create', (_event, options) => { + const win = new BrowserWindow({ + webPreferences: { + preload: path.join(rootPath, "preload.mjs"), + devTools: true + }, + ...options, + }); + + win.loadURL(`app://-/${options.url}`); +}); + const createWindow = () => { const windowSetting = getSetting('window'); @@ -15,14 +107,17 @@ const createWindow = () => { height: windowSetting.height, x: windowSetting.x, y: windowSetting.y, - fullscreen: windowSetting.fullscreen + fullscreen: windowSetting.fullscreen, + webPreferences: { + preload: path.join(rootPath, "preload.mjs") + } }); if (windowSetting.devTools) { win.webContents.openDevTools(); } - serveUrl(win); + win.loadURL("app://-"); win.on('close', () => { const bounds = win.getBounds(); diff --git a/src-electron/src/preload.ts b/src-electron/src/preload.ts new file mode 100644 index 0000000..2b128bc --- /dev/null +++ b/src-electron/src/preload.ts @@ -0,0 +1,12 @@ +import { contextBridge } from 'electron' +import { electronAPI } from './api.js'; + +if (process.contextIsolated) { + try { + contextBridge.exposeInMainWorld('electron', electronAPI); + } catch (error) { + console.error(error); + } +} else { + (window as any).electron = electronAPI; +} diff --git a/src-electron/tsconfig.json b/src-electron/tsconfig.json index 82a77fb..86a1e0c 100644 --- a/src-electron/tsconfig.json +++ b/src-electron/tsconfig.json @@ -25,5 +25,8 @@ }, "include": [ "src/**/*" + ], + "exclude": [ + "src/preload.ts" ] } \ No newline at end of file diff --git a/src-electron/tsconfig.preload.json b/src-electron/tsconfig.preload.json new file mode 100644 index 0000000..a854dac --- /dev/null +++ b/src-electron/tsconfig.preload.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "Preserve", + "moduleResolution": "bundler", + "resolveJsonModule": false + }, + "include": [ + "src/preload.ts" + ], + "exclude": [] +} \ No newline at end of file diff --git a/src/components/Header.svelte b/src/components/Header.svelte index a28821c..c7c4bb3 100644 --- a/src/components/Header.svelte +++ b/src/components/Header.svelte @@ -2,6 +2,7 @@ import { Icon, Squares2x2, ListBullet, Cog6Tooth } from "svelte-hero-icons"; import { gridLayout } from "../stores"; import { _ } from "svelte-i18n"; + import { openWindow } from "helpers/window"; export let searchTerm: string; @@ -15,31 +16,10 @@ async function createSettings() { console.log("Making settings widow"); - - try { - const tauri = await import("@tauri-apps/api/webviewWindow"); - const settingsWindow = new tauri.WebviewWindow("settings", { - url: "/settings", - title: "Settings", - }); - - settingsWindow.once("tauri://created", () => { - console.log("Window created"); - }); - - settingsWindow.once("tauri://error", (err) => { - console.log(err); - }); - - return; - } catch (e) {} - - const electron = await import("electron"); - const settingsWindow = new electron.BrowserWindow({ + openWindow({ + url: "/settings", title: "Settings", }); - - settingsWindow.loadFile("/settings"); } diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 0000000..a6a5784 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,7 @@ +import { electronAPI } from '../src-electron/src/api.js' + +declare global { + interface Window { + electron: typeof electronAPI; + } +} diff --git a/src/helpers/window.ts b/src/helpers/window.ts new file mode 100644 index 0000000..72a0961 --- /dev/null +++ b/src/helpers/window.ts @@ -0,0 +1,17 @@ +export async function openWindow(options: { url: string, title: string }) { + if (window.electron) { + window.electron.ipcRenderer.send("window/create", options); + return; + } + + const tauri = await import("@tauri-apps/api/webviewWindow"); + const settingsWindow = new tauri.WebviewWindow("settings", options); + + settingsWindow.once("tauri://created", () => { + console.log("Window created"); + }); + + settingsWindow.once("tauri://error", async (err) => { + console.log(err); + }); +} diff --git a/src/i18n.ts b/src/i18n.ts index 4581a1a..9629fab 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -2,7 +2,7 @@ import { register, init, getLocaleFromNavigator } from "svelte-i18n"; register("en", () => import("./locales/en.json")); -export const localeInitialized = init({ +await init({ fallbackLocale: "en", initialLocale: getLocaleFromNavigator() }); diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 83830ae..5e4f4f3 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -3,9 +3,8 @@ import Footer from "components/Footer.svelte"; import { Game, Region } from "models/Game"; import GameLibrary from "components/GameLibrary.svelte"; - import { localeInitialized } from "../i18n"; - let sonicGame = new Game( + const sonicGame = new Game( "Sonic Mania", "./icon0.png", "SEGA", @@ -14,7 +13,7 @@ "CUSA07023", 197927919, ); - let weAreDoomedGame = new Game( + const weAreDoomedGame = new Game( "WE ARE DOOMED", "./icon1.png", "Vertex Pop Inc.", @@ -23,7 +22,7 @@ "CUSA02394", 32903780, ); - let games = [sonicGame, weAreDoomedGame]; + const games = [sonicGame, weAreDoomedGame]; let filteredGames: Game[] = []; let searchTerm = ""; @@ -42,11 +41,9 @@
- {#await localeInitialized then} -
-
- -
-
- {/await} +
+
+ +
+
diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte index f3d7c59..864539d 100644 --- a/src/routes/settings/+page.svelte +++ b/src/routes/settings/+page.svelte @@ -45,28 +45,28 @@
-
    - {#each tabs as tab} -
  • - -
  • - {/each} -
-
- -
+
    + {#each tabs as tab} +
  • + +
  • + {/each} +
+
+ +
diff --git a/vite.config.js b/vite.config.js index b8d7614..ffae529 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,13 +1,35 @@ import { defineConfig } from "vite"; import { sveltekit } from "@sveltejs/kit/vite"; +import electron from 'vite-plugin-electron/simple'; import path from "path"; const host = process.env.TAURI_DEV_HOST; // https://vitejs.dev/config/ export default defineConfig(async () => ({ - plugins: [sveltekit()], - + plugins: [ + sveltekit(), + electron({ + main: { + entry: 'src-electron/src/main.ts', + vite: { + build: { + target: "esnext", + minify: false, + outDir: "build" + } + }, + }, + preload: { + input: 'src-electron/src/preload.ts', + vite: { + build: { + outDir: "build" + } + } + }, + }) + ], // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` // // 1. prevent vite from obscuring rust errors @@ -19,10 +41,10 @@ export default defineConfig(async () => ({ host: host || false, hmr: host ? { - protocol: "ws", - host, - port: 1421, - } + protocol: "ws", + host, + port: 1421, + } : undefined, watch: { // 3. tell vite to ignore watching `src-tauri` @@ -37,6 +59,7 @@ export default defineConfig(async () => ({ } }, build: { - minify: false + target: "esnext", + minify: false, } }));