From f97c8607504a88c3b39b0c6e2909c7f0c85d5d2a Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Fri, 15 Nov 2024 00:16:08 +0800 Subject: [PATCH] prefer throwing over typesafe errors --- .../src-tauri/icons/dmg-background.png | Bin 0 -> 16566 bytes apps/desktop/src-tauri/src/lib.rs | 3 +- apps/desktop/src-tauri/tauri.conf.json | 9 +- .../src/routes/(window-chrome)/(main).tsx | 3 + .../(window-chrome)/settings/recordings.tsx | 46 ++- .../(window-chrome)/settings/screenshots.tsx | 37 +-- .../src/routes/(window-chrome)/upgrade.tsx | 2 +- apps/desktop/src/routes/editor/Header.tsx | 7 +- .../routes/editor/editorInstanceContext.ts | 5 +- apps/desktop/src/routes/prev-recordings.tsx | 77 ++--- apps/desktop/src/utils/queries.ts | 19 +- apps/desktop/src/utils/tauri.ts | 270 ++++-------------- 12 files changed, 146 insertions(+), 332 deletions(-) create mode 100644 apps/desktop/src-tauri/icons/dmg-background.png diff --git a/apps/desktop/src-tauri/icons/dmg-background.png b/apps/desktop/src-tauri/icons/dmg-background.png new file mode 100644 index 0000000000000000000000000000000000000000..662fbecac03c7a4d3042ab49a95bab22c56591dc GIT binary patch literal 16566 zcmeIZX*`=-^e~zZhE_{e4K1au(`t=1Q&T6jHMiynDmBJT%t5PEO=+uWYbt7vn1di_ zkyBG@41yFVf*_O#g4{Uo|GoEjzu)(MIv?`e&$FJrR@UBo?X}ikd#$&o#`uQ@)RE0sw%kYDd3gy6N(cEa0(#r~3B+$N`Zh z*2_uPdq(#FfND6`{&O|};I6^rhxg1wj;&5}A?$)-66-&tOygHg&z~F53yuF){XkVl z`f8qT)iuAe`-L)(3x=M&*!)!{WyV|cwA{<$Z;$u3rB^w>A<>~qY3Q%-^y_2G{9c_b zye?O7VC%{8>d|owH<#ZdPl><$#8&oGU|CJfaF>OwCPn%o@?iIo)z8+P&x&N44w_m+P`kJA7?dJl#dA7&=De2&Lh z&ATrEE>;sga?<(;`t3i||EB3bk@#=t{QsjR%{IM;>BSVNd2Fs#Fi^qA#0(@VbXN}UgbFktZAVvC!-xTX3%=h<>Nb?#s+y_`Q{>9`!!mKwq z0-Na`fy4g=L;nTq{tGrZ0t^2OrX7K&jvh^ySY!KqWMCcRS%3Hreq>E;j|Lpdc?3K; zefroHjw3s4_?5*cLiXq}@Y~U2il7!_>ZOx1W%=R__vo&No3 z~oK9`TmrDFQ?y*f$vPNrJ^l0Pnp0F%g-Z&;|88EkNIU z09SNV$oB3D{`SFtCdePd0k`G;pWS&|urh2^N;10Or%B7)r_+E>JVzA#R-_z`XhhDD zu;$p76_&`|7GohT%f08TB`T*X0gk#y6KZY7tlQKWwH0`2ancI= z1#ui;nS|8^0Dj#I6x2Larm*W!C`=B3Wy;Yy-1r4L2e8bLx(xs%eQmx1_~#1CFN%J( z_6qPW@#uTpqAVw1w^8y0;BF!7^NSZQ}%z;kX z1BAb(G>gaR4@bOM(6$tDm$|F2wVby*2DpC22g`%Jc#4nJ{O2V8=S%;0Zuswv^xskP z|KPFt$kgAMtcT=HR&NTAB4cAch!_}+I9BQ4klpD147#wOSY{;QjbN$c-E)rBlHSby zj4~J__wx>#MzObG(n;7B#GONBtc5UfebQt2H^%~LRzKLvp@{)WJlvL|hSO)kezqyQ z_3lK>!6;O9%6!_NvI>n>9(bFnVkzjURf*moGI(vXU;;Fd-Q7i**< zYq=8)@P~t9=H#q^AgEGe&0?G|({qrxcCeh$jd7h9Ce|&|9a}yKN7lRTXs~- z!q=L728lsYbRfSJWVTvtg#MhtK{tTwY>ebb5w`a5mef!>p)Acjy`QQ{M=XC#Rk7Ht z`q2BT-Y~kWY`lTF)PaNFX<3Us&1~QhtXmcfGM9_m?Oi^8u+rdZ6I22yB4-J`X(%g4?whiKJ~|I<;+O$YrG$XR6fXzQg9ZwF zNB^Lxqppq8tw(R_Z}zk_A1+{)XZ3^N5&alwZJTQ5i|f5E_+yKD(OqBo*!E(G5#J8g zDXzxl1BXqDl+)TGrE&1xT4I>X~8gB#6yRJGggsREv)B zJ)pa+n$_EyvwBtE`7bcZ%OEbInMjLpp4IiA0~u7-{Tz~-?}<^Z zlhyMbV^NjZmOFmndgslHqcbqZG9F$QsP8PvSv|QLxxxVre*YYz-afheOFS{sp)W=x?QCVi714f(14s~Hn;EI|1UZ;dk>$h-|ec0wgf6Nm)hm>R8 zqIM&UJQpB$e12B8g|N1t4=68IxT~t|&|I#)4;)2uL2-6xH%yU%+rS2M*EUk$>92pa zUyChy?X$N2kCx;blV3?hB)^w_Jjl$6!LKApqPRH(rZ6!;J+N3?1U zrr@ml^j;g`8|naWPj6yxXm-J0zMm)elt+e}aYdh-J|!o*pNTZNJxNpDU&<$fgK)j< z9aJpxaA&q{NpIZYqk&=2fVxllK&fR=v@f?LHZtL{=WDC>n{r6Uvu|aeky{xn%h}}p zl@C#gYd48wQ90s`)PDumU1>s= zWSvOVrIbDAy(w}g5-+#c9B?YdQ$mEfeA@AXOqF%2)B5&$S~v!^NTnYTS1Z6Nox|C) z36UqCXU?oozGp@*KhEq9>M!FMja;1dz~!{kl-h7&YNqsII9-JKWu86nhaU~$HylJw zz%jQAxJJQnt;n6td5y|MDkxAZ@$+&{)M5MI(9BpA%`08Ge^0MGe-`OS3QmD-B>QNi zUrd|qmM(GVdKbCODDL!)6Z;SEkiMyo5VaT~Pvt|x<6l<3>7sfu!pE=?ZkaQ8v{iG` zbNq+8J?4LJHhW_q6Dw`T);iRGWjRprtu=Iibb{rx<{%mF_5!v?eK*GO7Gj5{(C6~9 zV=^(gwz7HGX{``yc1+KHuwamt1`o7!vd$e0dapxX^(l|s*xw9;o{$8-2365oe#lto zD;xBEX#`hgSzGRFr3W0T&`n&F33Tm@D@=+W`Yc6hTl>JUzP3>6afX6dW8akOPS$LI zW=~0SWz=dPwm=eJytTuV>jBC&(t;Cj%85m8Ro~lXynxO0m#rjFF^q6HK37=rn~L+Q z5_!|VOWq+Tsx54`V_gzW<%TN;<67xfu!s20Svt1y(T}SE0hnnRm8+szDKnqq*sy~lnTB34YF~CfWy0Nd zs>`)=$G@7#X`*%tCneKEdc%Q#)fnv7Q(x5Q8Ru>NlhN9!qE&T}_k$Gdww7Ixl|6c} z_YLBh>#P;!xNZZNUNhF10$)kz$HQmQ?Fh={+XMd-fVO_F3R~Eu#TN3i5i1P`52z?y zRH=8Uvb1)w^rM3F8(nh5wilsh?O3AVod~`7`x-7!+=V@BF0h5!-DC_1(cAH2mtLPI zV2yKya}NxFM6-s0x7F|B+L#N&#>kn?wF#w|T>PG%>aW==MY{t~t6yFYmtPy2q=1Zb zkM$M&p*IBU+^#Nss@Uuhig<0Hy*}eiT>psOuVc7Rf-yETC9CqwpLjMVcMvt7qcRtS zKGn7E<)jvJRugQUj43R&3I6H0GWf+~a!u7Mw_!D<4Izanc&JM$u!@Qp{G?ORNl%am zqRnrrVEi_AUeRGRgBZG3SqAjr)4kdU=3CyayHU7rbLSaKJ>{70Y$+qs@0XQP0dpVc z{S3RS)yrSb5qc722g31$^oTbm2S580BjMDG&O=sfhqf>yp<-&^H&AcqFIt2>vWDXI z8cUynty{ls!?y7>(-w3b&fiUXiqV-7q{0)z_F+Sw1sM)OkBeWn_iiF~Q+Vyp2FG{~ z(=-$1_l~TN;DHxCxXpsLYtOQL53;{+?aWjoY%=s~4_EvT&~7O&pBunCl4HQ@y?i=S z-@gelt9lXjpoV7=3%W6oN4p?&-@9<%-+RPzR1hcei=#5~1cNmQgpE1 zY9Q|61mSkYHe(uJS(0iqtOqS$&cDdnOkq><-qQ&upp2gzZ|?GrOpO-2;!8{0`5efb zfID2N2p*_sShpsrSNiN8j*HEIFQ3IjPd%G!4xYyL?ygBKB@G+f{%MfKMr=MrQjNeO za8N^Ve1|oo1+!sy#*R48=xTJ#y_j_(bs$Z4uDca+?jc*4IvDGz73EHPZdW+Z((c8` zyU@~yuS?vLGiCg;V)*IA&qDUfm0DE6sHS@UA0CjN61CuF5e^P)a&z0^=Po}*AJF%5 zQ|)s?#U`Ia)@j4pIM{Txmpi>fuTJw;Gp}B6s=LgJZ3&!`$WAuN_;qz4b(4d9*L<6i z@Gj(O2>%=->mVh#Pz}dD(77i}qptx)WmYD&HfqJAKVw}h<2a*aJwmPJpCAlA784TY zTNB5F$jmv$4Oyv_!tw6Zbl%EDT%!CX#!BL*T!;f2#!Irb<3guHHqe}I==4mOGQLQb zM9gWL#1a3^h;{1Va(C&D7<^NA+HxzsJ>l7xfUh@M|kcKZVmF;Rc*_ z_4@etD)K=lb%7p{`DvXc6T|r*7)?NL;awYNQY$b2yIywwGz>q5;=Ny6-7BR_x`CNj zdOp!&7?7kqrN7m|7VDXx=#K?KW2nZq}psTEqR*+d>S+@`%JWCoork zXNk(TIYoSMK{Pz~B0U0Lv=CLjnzCz#HHzr=cR@=wV=|`23+i70t&-J(Z@7=ijESSs zN@QSsz*R|&@PwMEk&uvnay9ia%;VBPaha#bG+p+lgUBG3b{>N})7v@g;(!v$ z6*q97omNU_{XWczw9eJ=jOB`vZOwavSH^ALm^ed9tY@GxzoqSoUF!_OK<&+7r2CSd zU|wJb60&()vLxlF^gt+Mg0J`OI7;lWvTfSdxO3YL@?0Qy+LL*X@jK<-MgHkO=#S7J zz39X4Oo94^#Dnm8XjIFK&!CN}9#-O3-P>@$Vi#)^SNN z*3D)eAERQ-S#>`na@|jnxtecb)pCfRX@mY$SUx1hoVGp_3AA*{|8Ou6K)|lNy<2wV z!b_Lhb^S5E{90~<&m;>SM5Ty(U+ckT)AmvnJhJuAPKupqZ2(1xN4Rt4Pj-iTxa=lE zcjhiF-WM7ZWAu3J#3x-*91EWEn<9UL<5BewA;R#hD2M${vR--mZ04`Vre$H-`eZ)= z?A?gS0L955aey3`xe($cWgm*?XVuS;%bIJIO81s7l7PuF1XF-NAuqK-9iHbmI4BKBUjL@Vca?nR<(3&zL(ehC4T^zuyP^0}a-gHpK2u zTk6#(C*ws_&Eh`hZFhV<*eZo*T8}kux;333q(}zOM}#vOhYx5Izy=vf^4uM@G7&cj zY{GITZf8J#%^@`T^VToNOJ=;HcvuxL*4e!3&5sWnYx{HN$1KHP)o|*>VZ{>yZfYw= z=AUUS67rF}pBSSk9;AcU%XM`%2R7t1{G*xZb^c|iKl-+bcsej{sk$F5oEC#Ik(8MH z-i5NUCv+<$dI?iRqvUinde90=HW&W6Kw64>zz7)2XLBg^(!t6H&N+gdU_J7vZZ^Zh zg+@4suvhI|HyQhTe{d8!Uh?z7T4R8_RAckuo?J#!zjBM*K-=#O!R)AE``}AIVqWPt zS+HAs@hCp=BH3y>YEVIm^xgH=03fBHa_XSn@cV9~VEB4oAzyG^TKx~YF$~z)4I$Vr zqCh7yy+V6_3TN1zz-n!|0bMrlc15ouR9N1_rjtv}(+sYA_>Oi0`Y*j>+Q=ckSVnh# zwAg69->hjN*xI~XqW(+>xk*Pg<0Uj0Wf$Svgqha{Pu7`{1W2t=C1F)Y*%<9t9WRF0WYK z&k3A*s5`ro3$(*@`favv`&im^-AR@V7C)0Dz+Q+d-r>k?*Fi7(fGXt;2FMqKtGy|D z&0KaD^?MA6r^&)d03<3?Kh52Wv;w($C9Jv7l1yWAKe>xXqA&a| z&e@97ZG)d4oqUy38|m@~ai>7?cCRv(cDb+@o%QFLu!O9*WFd)7U3MAty;Rm@U%{<> zBei--zJZJkYx>+;i*{p9}8s$xis9^_NnoIX%nbKMUA zR(g5NL-)4gl#x1uSQYu$CV00n!#ve)s%Af1>&Ko=bK!Nnm6}}f*Ir!zc(196&W?pC z#B5Y#Pu}3!UHg7tnX8)U#GvS5UMD{BJ~GDqdBLoSmw@fvH@* z>YGdIgoQUielI^Tq|o@0hX+g* z&L=@U$61FLgEUapJl(w)J%o%Uah&a~t`!nT;38A*B1Lv!uGlv`^6V3T0d2n%55hAB zZVNHybMlDIfj}>Gs*71VgcgGume6tI+C;y(NhLD^#o=$-L2FuqwxZXvCg(*PL>|;r z!XTl#H;zk>wVZf1@SXnW7SKESeA-u`cYe%a6RYs;l?u#3wzo;^_G(nvAXWaCpOv4y zq}+F@LOUYKe!n^CK`rt@Y()jzeLO&_F1a+lzfR@~+T50Kyj@#Wc4Klp;|I~t1pAg9 z9oO@Gp5mY}j)#jLw)XyW7GhD?xwH25_+|d=ohHT%BmE5L6!g-T?*O4W*h;OTaHtNV zXR=jnW_j*@#(Fa^)>S>|Q5Kb=VHsiht4In-vMNVL~_b<MLDEfevR39EPZFM>`C+Mt3G9zW?hMgu1y$JYeUexD8?-}W9yq>*fM z!^x&I4+2|FE*6FgDIj`d;=7Ad@YQCm!bPjcC!np(_Nk87Ss~0#mx=5=oI=~d;(gHP zNimQuMithOP@_&3vg$#9&d#UhY+taPsrp> z2WNIB53FxgQwI8Gv zk4Q*o*28)=+Xy{))aKHor|F}-3P} z@>K~eoNlZMM|mDDm6h`WZP!=qI@XI;vvTMU1fj!wPiFc=f0}7J1V+s!tX)kXzC_<8XJ{Mh zu_&f@Oq{gB#mRu5xtPuYf{1`c6Y&t&w_+eKE zUyAI#fsPH`l=4VBsIW-&%JDyTINA4`Zd$kd_qzKZsEeQ3G*ii@4%57q`{sYnNCN@h z6D@VhdYV@qjHCJaqv4{LDBs*W{1zP5y}8oG5 zldwa0zu4G(2Pk;nXcXmij`>vc#RRk@)-ov#O4E<>8MVFDp#H9omD3T<(j0Z1*6G9K zmc*TXf)2BA%dgXgD&0bz8r#T8ABItGHWe-_UiU_oD(=L25jTE+ zkRW96Xjh)8(z95Mlky#mou6uG^D<-8Dk{xYXCKPy!!#plYDEa?>L@ROCGHEnWSmGdm-`}HE|BymyQIjOrpQJ_(#c$TQ4ed5&rTz z=9_C7$-$v;FxZLn9F}PJAeao#yjBK@$6-&DHk+J@Eb@vS9sB+*OIK1-!8uk|Qqc;u zn-}I%A8K)CFYuVBaH`7;cs{9i%Fkd@@)YFxR5R%&aJO3>{e?f>i?HT#*}zTR$qu1? z%rYw+bOM2@EYS`-tMtN&YJLE^)*$R>+&_=L#{}E^m zn#rpWV-r|vf0La|{P4oFblgW?Wo$iqpVvv(6pGCbmT}MHXR7q?1k^rFhv@9grov`s z?wr{15A&%@D}}8|G_&03)Qep)cp9be{NJn;sje^lGFd$WI)2C0!QHiwS(iH-*L&lO zFQ*22)t@){(Q8w^Cj9zB>T!fy?681~G`@~PPzj&*2=Ov7<)@6$8gJrtQq>lEe<^I^ zq>Jjr4qN;MI)oUj2-V!Nr2{V+&Svfxmr_p#o{bF_thJYI5O(hS%Yxf2yk9~GG<`=m znm?^xBO&vEvq<))t;4i@$=?~;q5Wd0AVm=YldcTKaleQLNafP@B5>}OFbCuS z9C(d~0(OwKy|LE0PjhVm8RcHUhf+;kH$Lhn8&vM}>r#Xne>zr~zB_b^&(835Y7;AL znyZ#RlybSrY z^57R4$aKFGN))d`K+2gZvlU|zMiU-b|AavzMCSY-Uz!T zdC>qz^_ICZHzf8OSfUh7AJqSb#hy9_0QCL)4>!FQt15Ita z2U+i@sa%^6J(vhP3^mYhmJt#r?WK^R5qJgP_^ReaZSn+4BZGZLDl|v8H=i$Y%rdte zJCQkcR^j+Nf303iU5%hf@XtT!Gbb@%*YAMxaVBg#04UhQH9!?OKk%e)Unupul8zu~ zUwE{?VMb*GW~7RH&Q-1kc|m}6oglQ?KnH_(25I)eSqcvmYEYEm$>1zQnV+S9~17OnIH|FzFMDBIFvQwDrBC>a+>M@%^-R_A%VAq`~8tJF%C*IR8!y=pVvNi;H z9g4u4yw#BXo@pM#2nRx=5AV6Hr5Ov9o^-NDXh@GjGq-;1#-Cp8#($_{&3jQ>r>mW^ zGEg?zP76ggCCzgY{(r9gof@NT({QW`5nv;=#-mrrgrF_C?cpQ#@jso#EQsqxgH z7FsFsi9x}c?+fxB-AcwPv*&CFac0 z8r&nOdC{+eFwcnLi|&;#H@*~U!kKUd7>*}kD<@j}r1iIRid5a%>Frum!9F4)S7>T$ z0*CJ~z9s7fLO0PyRT_QFe_^M0uzZIhHG}%*e+cMyO*PJw*AR@6+$p>1tp& zALnhoZoVo+SprFI4kI-OKN@M%=7B!mkc|er>f|0;A~pPwjVj!fOBF>x5GJ>}0YG=J z3dS4*tL&X6bfSF9HPg~hvlHbnBYJ5{yU0#h`LUVZvq{mq`e{D6FurVc#(gOG%YrB? zUaSs#tgg8><38d)r`U7*%-C_Ta@zd}(|Jj1B8Kq$pskK}85;20=3+f2x77?l{dznDiRR{x}|gB+6aGdI2BT1 zr^nV{(2$E%X`OwoOTIg`h=qRjt`A<}!ftnWP~u{W)Ygch1Gur5TUDH4;!4Y5Q~Tf5 zhjE?wB9YX>(#8>qsYRRsgvM+ACWV5XRl6;vm6GnH)_N`7Bbx+QN!`aMHJRvy?foZifBK@le}kKu$Fz}EtMry*{%N^wy~sn%HOHA|L)(mf3-UqC02(Ggwxw{ zDOXy&1PdBB;0Zs+>8((MX}Q)jG5KkC&4nh9XLD9N=^@-^G}nH@?0m1ae8Gmn(K`cR z82OgBXTHCkHx`}tOzT*?cm*|4B8=Yu+;`vRE%>lC2Bt&JOi@GSzY+r_$6cO@}L~cLC5E8^?gN+=YnQUXuosuthfPvkzKhZtEA2- z?7S#Hnw8PR(rJ(#*x(m&Nkf)%R-&ZbVWU;Dp6Ba5q@d$ZTCsJAJ&NDVV4Y+0SM{1b zZ}H2#6lKn)8rWLU)V*0&0#(5=r;$GYNvT5ejV_x@p>8a>mCTHQ7({buWa0W>i1yyX z5(Y9!=FtQfp5&^VuiiaY3`r-qOLW&McqDl|R_|F4h78m`=FTCsss16#iAGT2po0zF zDB;7EMRY^fJ9U&n-v=ucI>GtjuEI|XaToq1D(pvc6zZ?_rKe-MS5)@VHz~^pP|{Eb zd7jQ0*TZod+5~FxRzGI>8m78mse=Sgr{5!!@2ru9nRq6`(f|>)Qf|g*>cyn2W;|#A zX-2XQOv_Z#cFORVS#$0=HkOH--r5?P;oI=NwpKtuKA6Wmi!j#IT)gC_D>R16(#E$V zQ*-aCpwHFZ7&ZCLkv7j`7jih|`p!dE57rrbHOJFXv3+~t-u1-~JS`307Uu;^T+Za} zOhion9F;pOJGMdHw56um6GPvg1`;iw_!;(t4NGm}4`4IDKgEM13v)hoRjU~pR5sp9 zpibafhoUC?+EXgnX@v6CF@NuY`2}s4i7)2wQ%G6ker2pYFt29^O}vpt8V6x#?nhX_ zky2(8OEt2vE_HO4r78Jr&Rx1pKz{yt@}Oo)rhCso+KBnsUJlOeWu|T-PB`I-AJ7Vc znPeZq?56)b@l>Ddi#FLLOAdBoYR4OIKit}78Ik*#Y~xv5zA&{aJ*J2F@Zv?8o4Lx|GATH}HV9L$C3*-2XkKNAt({Pht6 z!&WWZBD-k$J`;jGrVKkSZhMVAhg2tZYS!GPOLX*RBm4I!gU1uM^1t&MK}|yX{h*X@ z$%>b#MexQ)4+Ewa6;!>mzU|oi2;0?tp$amSuXsF7EK}hX^;|nw^zj6nm|{%2ad|an z^PK8s-tDfCr#uk{K=HO`O`_#8KUg}Q)NN!x{bW8*AG?Mpd1E=1wAT+SIGSH2+l)O~ zspPEA{}Xx?G{qA`o)s4_oAJh{vv1@e(^!`>iQaeS(|L1YUCv?%*|rs(%gEn)x?V#J zy|+ERx`M53-V?XWbZws5VD@Va%0k~N$ZmsIHnnsj%IIo=W|q2(QzD85o$CA*Qsn7u zbqual!mA9Uax$udx>%!J3N;cT z1hYyhL^Y$l4-&`5((}Aa|IG3jY5fX18MraSTAwTe=tNBjD2aAqdX5{VMzHF)&D!Ms zfZcwJj4DXyC2DPhGmweAJAt<-*Uqu>DtTljgV8P2bp}sbDetEl7!?Lp#fEwoxY*Dm zX$Ca+u(1~RH{&1bjn_bB+6IvS$ zhnroAkv;?mUT#ES@W{F84{J^28T5Hk@T)WBSl^5Lo)a~pHWeS8F3NL4rNJTl88S3i zxR1<`p{r=^{WRk9|CLe7N+yj7+yAN;C_EAB)&xucY$PJ#7m<$b+j~G(H%KFes}1#Z zaSHYzJ(}AX6}oNujpjMQ@&cy0n@yUyd_gHYbR6Om#J&h;Lc`i zL*swx6xiXp?dMs17W#Lvy)s1rv1uB~{3TM{+ls09=1H<8zyj+4nOJCPi;qY8Xwq{o z{o}_35H&F;1fwDcpQXCJ{R0v7z8s#HjK}_7c9u#DLCe0o+RUo-sg=Lg{z}{?0{{`Y z!DbC;|8wyKm*qrbX>azaEc5-#iKHEUt`MyiEXuKW8D_>AYEjY zj&ps8N51ZtmIS$O082mDvw)7u7dtP1Ncj9P2w(eF(*pi>H2y1Oy1KHgxL>)P6Jl|) z&iN6fsBt&`VrN`M;lww`Ca3K-mj!gUrpuuejzw9{#peXTMW0m!byPjv&8mz6{8wB2 mUmf*-) -> Result Ok(recording) => state.set_current_recording(recording), Err(error) => { eprintln!("{error}"); - return Err("Failed to set up recording".into()); + return Err(format!("Failed to set up recording: {error}")); } }; @@ -2470,6 +2470,7 @@ pub async fn run() { AuthenticationInvalid, audio_meter::AudioInputLevelChange ]) + .error_handling(tauri_specta::ErrorHandlingMode::Throw) .typ::() .typ::() .typ::() diff --git a/apps/desktop/src-tauri/tauri.conf.json b/apps/desktop/src-tauri/tauri.conf.json index 880268de..5939f031 100644 --- a/apps/desktop/src-tauri/tauri.conf.json +++ b/apps/desktop/src-tauri/tauri.conf.json @@ -6,7 +6,7 @@ "build": { "beforeDevCommand": "node scripts/prepareSidecars.js && pnpm localdev", "devUrl": "http://localhost:3001", - "beforeBuildCommand": "node scripts/prepareSidecars.js && pnpm build", + "beforeBuildCommand": "node scripts/prepareSidecars.js && pnpm turbo build --filter @cap/desktop", "frontendDist": "../.output/public" }, "app": { @@ -40,6 +40,11 @@ "icons/icon.icns", "icons/icon.ico" ], - "externalBin": ["../../../target/binaries/ffmpeg"] + "externalBin": ["../../../target/binaries/ffmpeg"], + "macOS": { + "dmg": { + "background": "./src-tauri/icons/dmg-background.png" + } + } } } diff --git a/apps/desktop/src/routes/(window-chrome)/(main).tsx b/apps/desktop/src/routes/(window-chrome)/(main).tsx index ed128d0c..d1c83df8 100644 --- a/apps/desktop/src/routes/(window-chrome)/(main).tsx +++ b/apps/desktop/src/routes/(window-chrome)/(main).tsx @@ -84,6 +84,9 @@ export default function () { await commands.stopRecording(); } }, + onError: (e) => { + alert("An error occurred, here are the details:\n" + e.toString()); + }, })); createAsync(() => getAuth()); diff --git a/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx b/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx index 01794b9d..46232eaf 100644 --- a/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx +++ b/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx @@ -16,32 +16,28 @@ export default function Recordings() { const fetchRecordings = createQuery(() => ({ queryKey: ["recordings"], queryFn: async () => { - try { - const result = await commands.listRecordings(); - if (result.status === "ok") { - const recordings = await Promise.all( - result.data.map(async (file) => { - const [id, path, meta] = file; - const thumbnailPath = `${path}/screenshots/display.jpg`; + const result = await commands + .listRecordings() + .then( + () => + Promise.resolve([]) as ReturnType + ); - return { - id, - path, - prettyName: meta.pretty_name, - isNew: false, - thumbnailPath, - }; - }) - ); - return recordings; - } else { - console.error("Failed to list recordings:", result.error); - return []; - } - } catch (error) { - console.error("Error fetching recordings:", error); - return []; - } + const recordings = await Promise.all( + result.map(async (file) => { + const [id, path, meta] = file; + const thumbnailPath = `${path}/screenshots/display.jpg`; + + return { + id, + path, + prettyName: meta.pretty_name, + isNew: false, + thumbnailPath, + }; + }) + ); + return recordings; }, })); diff --git a/apps/desktop/src/routes/(window-chrome)/settings/screenshots.tsx b/apps/desktop/src/routes/(window-chrome)/settings/screenshots.tsx index e21f104d..92d42fea 100644 --- a/apps/desktop/src/routes/(window-chrome)/settings/screenshots.tsx +++ b/apps/desktop/src/routes/(window-chrome)/settings/screenshots.tsx @@ -16,25 +16,26 @@ export default function Screenshots() { const fetchScreenshots = createQuery(() => ({ queryKey: ["screenshots"], queryFn: async () => { - const result = await commands.listScreenshots(); - if (result.status === "ok") { - const screenshots = await Promise.all( - result.data.map(async (file) => { - const [id, pngPath, meta] = file; - - return { - id, - path: pngPath, - prettyName: meta.pretty_name, - isNew: false, - thumbnailPath: pngPath, - }; - }) + const result = await commands + .listScreenshots() + .catch( + () => + Promise.resolve([]) as ReturnType ); - return screenshots; - } else { - return []; - } + const screenshots = await Promise.all( + result.map(async (file) => { + const [id, pngPath, meta] = file; + + return { + id, + path: pngPath, + prettyName: meta.pretty_name, + isNew: false, + thumbnailPath: pngPath, + }; + }) + ); + return screenshots; }, })); diff --git a/apps/desktop/src/routes/(window-chrome)/upgrade.tsx b/apps/desktop/src/routes/(window-chrome)/upgrade.tsx index 65f1f8ca..c4e4cfbc 100644 --- a/apps/desktop/src/routes/(window-chrome)/upgrade.tsx +++ b/apps/desktop/src/routes/(window-chrome)/upgrade.tsx @@ -68,7 +68,7 @@ export default function Page() { const checkUpgradeStatus = async () => { const result = await commands.checkUpgradedAndUpdate(); - if (result.status === "ok" && result.data === true) { + if (result) { setUpgradeComplete(true); } }; diff --git a/apps/desktop/src/routes/editor/Header.tsx b/apps/desktop/src/routes/editor/Header.tsx index 5fdf572b..a253ee33 100644 --- a/apps/desktop/src/routes/editor/Header.tsx +++ b/apps/desktop/src/routes/editor/Header.tsx @@ -40,9 +40,7 @@ export function Header() { )} >
-
+
@@ -170,14 +168,13 @@ function ShareButton() { const uploadVideo = createMutation(() => ({ mutationFn: async () => { - const res = await commands.uploadRenderedVideo( + await commands.uploadRenderedVideo( videoId, project ? project : presets.getDefaultConfig() ?? DEFAULT_PROJECT_CONFIG, null ); - if (res.status !== "ok") throw new Error(res.error); }, onSuccess: () => metaActions.refetch(), })); diff --git a/apps/desktop/src/routes/editor/editorInstanceContext.ts b/apps/desktop/src/routes/editor/editorInstanceContext.ts index d423ed6c..d0e39e7f 100644 --- a/apps/desktop/src/routes/editor/editorInstanceContext.ts +++ b/apps/desktop/src/routes/editor/editorInstanceContext.ts @@ -18,10 +18,9 @@ export const [EditorInstanceContextProvider, useEditorInstanceContext] = const [editorInstance] = createResource(async () => { const instance = await commands.createEditorInstance(props.videoId); - if (instance.status !== "ok") throw new Error("Failed to start editor"); const [ws, isConnected] = createImageDataWS( - instance.data.framesSocketUrl, + instance.framesSocketUrl, setLatestFrame ); @@ -33,7 +32,7 @@ export const [EditorInstanceContextProvider, useEditorInstanceContext] = } }); - return instance.data; + return instance; }); return { diff --git a/apps/desktop/src/routes/prev-recordings.tsx b/apps/desktop/src/routes/prev-recordings.tsx index 24a2ca35..631415f8 100644 --- a/apps/desktop/src/routes/prev-recordings.tsx +++ b/apps/desktop/src/routes/prev-recordings.tsx @@ -82,9 +82,12 @@ export default function () { const allMedia = createMemo(() => [...recordings, ...screenshots]); return ( -
+
(null); const normalizedPath = media.path.replace(/\\/g, "/"); const mediaId = normalizedPath.split("/").pop()?.split(".")[0]!; - + const type = media.type ?? "recording"; const fileId = type === "recording" @@ -123,16 +126,12 @@ export default function () { const copyMedia = createMutation(() => ({ mutationFn: async () => { if (isRecording) { - const res = await commands.copyRenderedVideoToClipboard( + await commands.copyRenderedVideoToClipboard( mediaId, presets.getDefaultConfig() ?? DEFAULT_PROJECT_CONFIG ); - if (res.status !== "ok") throw new Error(res.error); } else { - const res = await commands.copyScreenshotToClipboard( - media.path - ); - if (res.status !== "ok") throw new Error(res.error); + await commands.copyScreenshotToClipboard(media.path); } }, })); @@ -156,49 +155,28 @@ export default function () { ? suggestedName : `${suggestedName}${extension}`; - const savePathResult = await commands.saveFileDialog( + const savePath = await commands.saveFileDialog( fullFileName, fileType ); - if ( - savePathResult.status !== "ok" || - !savePathResult.data - ) { + if (!savePath) { return false; } - const savePath = savePathResult.data; - if (isRecording) { const renderedPath = await commands.getRenderedVideo( mediaId, presets.getDefaultConfig() ?? DEFAULT_PROJECT_CONFIG ); - if (renderedPath.status !== "ok" || !renderedPath.data) { + if (!renderedPath) { throw new Error("Failed to get rendered video path"); } - const copyResult = await commands.copyFileToPath( - renderedPath.data, - savePath - ); - if (copyResult.status !== "ok") { - throw new Error( - `Failed to copy file: ${copyResult.error}` - ); - } + await commands.copyFileToPath(renderedPath, savePath); } else { - const copyResult = await commands.copyFileToPath( - media.path, - savePath - ); - if (copyResult.status !== "ok") { - throw new Error( - `Failed to copy file: ${copyResult.error}` - ); - } + await commands.copyFileToPath(media.path, savePath); } return true; @@ -206,7 +184,7 @@ export default function () { })); const uploadMedia = createMutation(() => ({ mutationFn: async () => { - let res: Result; + let res: UploadResult; if (isRecording) { res = await commands.uploadRenderedVideo( mediaId, @@ -217,11 +195,7 @@ export default function () { res = await commands.uploadScreenshot(media.path); } - if (res.status === "error") { - throw new Error(res.error); - } - - switch (res.data) { + switch (res) { case "NotAuthenticated": throw new Error("Not authenticated"); case "PlanCheckFailed": @@ -239,17 +213,14 @@ export default function () { const [metadata] = createResource(async () => { if (isRecording) { - const result = await commands.getVideoMetadata( - media.path, - null - ); - - if (result.status !== "ok") { - console.error(`Failed to get metadata: ${result.status}`); - return; - } - - const [duration, size] = result.data; + const result = await commands + .getVideoMetadata(media.path, null) + .catch((e) => { + console.error(`Failed to get metadata: ${e}`); + }); + if (!result) return; + + const [duration, size] = result; console.log( `Metadata for ${media.path}: duration=${duration}, size=${size}` ); diff --git a/apps/desktop/src/utils/queries.ts b/apps/desktop/src/utils/queries.ts index 9d8b0f60..ce4ae1e3 100644 --- a/apps/desktop/src/utils/queries.ts +++ b/apps/desktop/src/utils/queries.ts @@ -22,18 +22,12 @@ export const listScreens = queryOptions({ const getOptions = queryOptions({ queryKey: ["recordingOptions"] as const, - queryFn: async () => { - const o = await commands.getRecordingOptions(); - if (o.status === "ok") return o.data; - }, + queryFn: () => commands.getRecordingOptions(), }); const getCurrentRecording = queryOptions({ queryKey: ["currentRecording"] as const, - queryFn: async () => { - const o = await commands.getCurrentRecording(); - if (o.status === "ok") return o.data[0]; - }, + queryFn: () => commands.getCurrentRecording().then((d) => d[0]), }); const listVideoDevices = queryOptions({ @@ -57,9 +51,8 @@ export function createVideoDevicesQuery() { export const listAudioDevices = queryOptions({ queryKey: ["audioDevices"] as const, queryFn: async () => { - const r = await commands.listAudioDevices(); - if (r.status === "ok") - return r.data.map((name) => ({ name, deviceId: name })); + const devices = await commands.listAudioDevices(); + return devices.map((name) => ({ name, deviceId: name })); }, reconcile: "name", refetchInterval: 1000, @@ -99,9 +92,7 @@ export function createOptionsQuery() { const options = createQuery(() => ({ ...getOptions, select: (data) => { - if (data && state) { - return { ...data, ...state }; - } + return { ...data, ...state }; }, })); diff --git a/apps/desktop/src/utils/tauri.ts b/apps/desktop/src/utils/tauri.ts index 79d85bd9..577a59c2 100644 --- a/apps/desktop/src/utils/tauri.ts +++ b/apps/desktop/src/utils/tauri.ts @@ -5,61 +5,26 @@ export const commands = { -async getRecordingOptions() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("get_recording_options") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async getRecordingOptions() : Promise { + return await TAURI_INVOKE("get_recording_options"); }, -async setRecordingOptions(options: RecordingOptions) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("set_recording_options", { options }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async setRecordingOptions(options: RecordingOptions) : Promise { + return await TAURI_INVOKE("set_recording_options", { options }); }, -async startRecording() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("start_recording") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async startRecording() : Promise { + return await TAURI_INVOKE("start_recording"); }, -async stopRecording() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("stop_recording") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async stopRecording() : Promise { + return await TAURI_INVOKE("stop_recording"); }, -async pauseRecording() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("pause_recording") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async pauseRecording() : Promise { + return await TAURI_INVOKE("pause_recording"); }, -async resumeRecording() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("resume_recording") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async resumeRecording() : Promise { + return await TAURI_INVOKE("resume_recording"); }, -async takeScreenshot() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("take_screenshot") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async takeScreenshot() : Promise { + return await TAURI_INVOKE("take_screenshot"); }, async listCameras() : Promise { return await TAURI_INVOKE("list_cameras"); @@ -70,13 +35,8 @@ async listCaptureWindows() : Promise { async listCaptureScreens() : Promise { return await TAURI_INVOKE("list_capture_screens"); }, -async listAudioDevices() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("list_audio_devices") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async listAudioDevices() : Promise { + return await TAURI_INVOKE("list_audio_devices"); }, async showPreviousRecordingsWindow() : Promise { await TAURI_INVOKE("show_previous_recordings_window"); @@ -84,91 +44,41 @@ async showPreviousRecordingsWindow() : Promise { async closePreviousRecordingsWindow() : Promise { await TAURI_INVOKE("close_previous_recordings_window"); }, -async setFakeWindowBounds(name: string, bounds: Bounds) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("set_fake_window_bounds", { name, bounds }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async setFakeWindowBounds(name: string, bounds: Bounds) : Promise { + return await TAURI_INVOKE("set_fake_window_bounds", { name, bounds }); }, -async removeFakeWindow(name: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("remove_fake_window", { name }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async removeFakeWindow(name: string) : Promise { + return await TAURI_INVOKE("remove_fake_window", { name }); }, async focusCapturesPanel() : Promise { await TAURI_INVOKE("focus_captures_panel"); }, -async getCurrentRecording() : Promise, null>> { - try { - return { status: "ok", data: await TAURI_INVOKE("get_current_recording") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async getCurrentRecording() : Promise> { + return await TAURI_INVOKE("get_current_recording"); }, async renderToFile(outputPath: string, videoId: string, project: ProjectConfiguration, progressChannel: TAURI_CHANNEL) : Promise { await TAURI_INVOKE("render_to_file", { outputPath, videoId, project, progressChannel }); }, -async getRenderedVideo(videoId: string, project: ProjectConfiguration) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("get_rendered_video", { videoId, project }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async getRenderedVideo(videoId: string, project: ProjectConfiguration) : Promise { + return await TAURI_INVOKE("get_rendered_video", { videoId, project }); }, -async copyFileToPath(src: string, dst: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("copy_file_to_path", { src, dst }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async copyFileToPath(src: string, dst: string) : Promise { + return await TAURI_INVOKE("copy_file_to_path", { src, dst }); }, -async copyRenderedVideoToClipboard(videoId: string, project: ProjectConfiguration) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("copy_rendered_video_to_clipboard", { videoId, project }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async copyRenderedVideoToClipboard(videoId: string, project: ProjectConfiguration) : Promise { + return await TAURI_INVOKE("copy_rendered_video_to_clipboard", { videoId, project }); }, -async copyScreenshotToClipboard(path: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("copy_screenshot_to_clipboard", { path }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async copyScreenshotToClipboard(path: string) : Promise { + return await TAURI_INVOKE("copy_screenshot_to_clipboard", { path }); }, -async openFilePath(path: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("open_file_path", { path }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async openFilePath(path: string) : Promise { + return await TAURI_INVOKE("open_file_path", { path }); }, -async getVideoMetadata(videoId: string, videoType: VideoType | null) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("get_video_metadata", { videoId, videoType }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async getVideoMetadata(videoId: string, videoType: VideoType | null) : Promise<[number, number]> { + return await TAURI_INVOKE("get_video_metadata", { videoId, videoType }); }, -async createEditorInstance(videoId: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("create_editor_instance", { videoId }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async createEditorInstance(videoId: string) : Promise { + return await TAURI_INVOKE("create_editor_instance", { videoId }); }, async startPlayback(videoId: string) : Promise { await TAURI_INVOKE("start_playback", { videoId }); @@ -200,21 +110,11 @@ async doPermissionsCheck(initialCheck: boolean) : Promise { async requestPermission(permission: OSPermission) : Promise { await TAURI_INVOKE("request_permission", { permission }); }, -async uploadRenderedVideo(videoId: string, project: ProjectConfiguration, preCreatedVideo: PreCreatedVideo | null) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("upload_rendered_video", { videoId, project, preCreatedVideo }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async uploadRenderedVideo(videoId: string, project: ProjectConfiguration, preCreatedVideo: PreCreatedVideo | null) : Promise { + return await TAURI_INVOKE("upload_rendered_video", { videoId, project, preCreatedVideo }); }, -async uploadScreenshot(screenshotPath: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("upload_screenshot", { screenshotPath }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async uploadScreenshot(screenshotPath: string) : Promise { + return await TAURI_INVOKE("upload_screenshot", { screenshotPath }); }, async getRecordingMeta(id: string, fileType: string) : Promise { return await TAURI_INVOKE("get_recording_meta", { id, fileType }); @@ -225,77 +125,32 @@ async openUpgradeWindow() : Promise { async openSettingsWindow(page: string) : Promise { await TAURI_INVOKE("open_settings_window", { page }); }, -async saveFileDialog(fileName: string, fileType: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("save_file_dialog", { fileName, fileType }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async saveFileDialog(fileName: string, fileType: string) : Promise { + return await TAURI_INVOKE("save_file_dialog", { fileName, fileType }); }, -async listRecordings() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("list_recordings") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async listRecordings() : Promise<([string, string, RecordingMeta])[]> { + return await TAURI_INVOKE("list_recordings"); }, -async listScreenshots() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("list_screenshots") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async listScreenshots() : Promise<([string, string, RecordingMeta])[]> { + return await TAURI_INVOKE("list_screenshots"); }, -async checkUpgradedAndUpdate() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("check_upgraded_and_update") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async checkUpgradedAndUpdate() : Promise { + return await TAURI_INVOKE("check_upgraded_and_update"); }, -async openExternalLink(url: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("open_external_link", { url }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async openExternalLink(url: string) : Promise { + return await TAURI_INVOKE("open_external_link", { url }); }, -async setHotkey(action: HotkeyAction, hotkey: Hotkey | null) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("set_hotkey", { action, hotkey }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async setHotkey(action: HotkeyAction, hotkey: Hotkey | null) : Promise { + return await TAURI_INVOKE("set_hotkey", { action, hotkey }); }, -async deleteAuthOpenSignin() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("delete_auth_open_signin") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async deleteAuthOpenSignin() : Promise { + return await TAURI_INVOKE("delete_auth_open_signin"); }, -async resetCameraPermissions() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("reset_camera_permissions") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async resetCameraPermissions() : Promise { + return await TAURI_INVOKE("reset_camera_permissions"); }, -async resetMicrophonePermissions() : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("reset_microphone_permissions") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async resetMicrophonePermissions() : Promise { + return await TAURI_INVOKE("reset_microphone_permissions"); }, async isCameraWindowOpen() : Promise { return await TAURI_INVOKE("is_camera_window_open"); @@ -303,13 +158,8 @@ async isCameraWindowOpen() : Promise { async seekTo(videoId: string, frameNumber: number) : Promise { await TAURI_INVOKE("seek_to", { videoId, frameNumber }); }, -async sendFeedbackRequest(feedback: string) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("send_feedback_request", { feedback }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} +async sendFeedbackRequest(feedback: string) : Promise { + return await TAURI_INVOKE("send_feedback_request", { feedback }); }, async positionTrafficLights(controlsInset: [number, number] | null) : Promise { await TAURI_INVOKE("position_traffic_lights", { controlsInset });