From 3bd65da75abbbb49d525cfc7629edfa8e570de42 Mon Sep 17 00:00:00 2001 From: CJ Pais Date: Sat, 2 Aug 2025 19:26:30 -0700 Subject: [PATCH] toast stuff? --- bun.lockb | Bin 68001 -> 68421 bytes package.json | 1 + src/App.tsx | 2 + src/components/settings/HandyShortcut.tsx | 47 +++++++++++++++++++--- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/bun.lockb b/bun.lockb index fe07be327409b101d983eeea5f61cc245fc6ffa8..8fbc20a54ef16ca3b148932744f6794ac775dde1 100755 GIT binary patch delta 10484 zcmeHNdstOf+TZKQQIB{;6y$6VC|Ib79By(GJSV)MbTq}p<55wOi-3SAYM>~`(G)E6 z@^%p$N;GF=)UwD#%?oBKmNibfMrOhu*TOgFwtzu&v}*>jra`aMtIf9>b_t>62u z^{)H7*WPRI)j(daKJK;25|)s$D0S7Oypj)t?!ELu!v_n_z4!6>mQgp~`qJypA18lZ z=X0Q&kofw|W=DVBFLrOPhzcuTP+FR|NRpmGib0ZGi}JE_7Q=)(Nm6&{1H9Du^_yGQ zRX4%Hh{#58H*jfo>4L&sNy;mqyQHu<2D($4_(XBf)(T9|>l= zzF>cFS1{-Q!duPv9+>UUsd}}m2|@rO>fH(J!Cb&n)xebt<^m?U_2FPHU=Wz?dV#s3 z+h{#E>?1IzzwOpff;s=91;xcn$|NZci9yh1aG+Ezx$Yo$UqoC7b3!Xv2JZp)1Fr+$ z4W0)M29I*MePH?E#Us(9d2F&=5h+af#7s^d<5&&i0B2u4Az5rDh_s) zBwuh*;o?G`+M{SyPw0!Y%d+Pd=Sfph8anOT1v~E99JGon91b1`4ghn5zCvUO_@bK+ zfRW@PFgLUeT+N1)A#e-hz&rx}U^c8n1(-h9u~11efp>zrp=-fxmk(yUd%@hZXfThQ zpF6z+!^ZaSgL#C{f_bWsg1H0t!zW+sWXxzAqIUcYm^<`FxN27m=K5=gstqm$b9v2( z=PBOd=EuN1a8D!uU~nmgc|}$qiBwD53-&?myy69Ovy026dbe%?^Dx`MJiHX6w!T-a zTFbZ4xwTbp?mbL(w4(C7@*GK$HX>gSq?ds)V6L%o>L^Tvj$yBMjf+=@H6F~}8Up6- zJeZ(1AH`%BXXoZsK*{2xCVOBeO#uAg2ix2!EUA87hqU)FjTXSzsIE~o3e!r7-Nh0KIBf`ZVJ_o=O?O_yw-zP?sbPEKE&;RFV6B$_3t z!I+@ab)(C^R^9k+)VG&aJVef3HvK^i@o38Gm8}03Qko*AVt&UdQY|Dk_59!B{NYC9 zmDFrVXl}0*F9`Q4QMVwCrl8&_UOrkGDM!MPW5jj5GB7Ofi zX*yQl8A{v%NV65m4|lJcV+kZQ2<5#FDU-57QoOKWDj7r-IR~I}EU-?>8j!4y!~!r| zksg7Rqe!6r(Hv*SaT& z(^QAJzaVZr;&i+y@G>S@qb2DcE=sH<=MbCzB}GRi;wx$!V$%(ep}yf(v6r0THeEz4 zZG%!xZQ(XUE7tjYQIFK&v%M1xPePlb6nrf_!SD^VL};Dpns%xFa{dRWpm#I{c>oyJ9{MSTOdtU8W4arvXmPj9wa&1 zCeDyE+NSHBOxvQZhG|&v)$9#n3E~lwV{GCra>l?Qg|@|5^((OA&!qa8WPKZ?>53F< zgfTw1uyP?cH-4$;AhwP2G)$aIe zP53F9D|p0R!GGZU{#(O;YS$T+JnF89Sx-UM0A;QECC5^PH9&Fj?NE3$b^z?q&jWn@ zGv*uN1tsHy z^$P%(^$x(-51H*Q164-WK=F_|=5#PgT+B)q{HkjCg(N+ATe2`rWg7@Z(d{LMHBiE`0mfHQq-~Ctp10 z*JbsB>jgWU7nh`8Klb}0;-QZ0HQ_6-e@!=1O|&o7F1k=hs)KfqG*Z?`yD(7WNC!NZKR{njAR(?pk`<#qwT_n4nZpzW2B%lcHv8fV;p2kGtzlzy-7}U z&{=3J((J;YTA@{pHB!V_y9l7lu?}IP3kYQj8|R=)^bOB)!h28HE!)X=5WNJg0LeWzkVg%J9w9++%HcHBL&_|g@s?W5GRBF$3 zh>?^!)geYv9m3Ic3*i__cR1)9hmrO<>|!i+I2>XeWlVF3bZSI+FA1kZ*vaX{oJ_}@ zIPGEr8Kz@Spp{Iwi-~jyTEPs=$qc*5pu!mrF_~Hr-cRyO2j21*BFv;#gi|Rb%Yn^V zCBkWR0ilz^W;w)kT7_^1wIQ5I(X$;Qi)suVm_wTpW>Y)Dxs;mi5IIzb zFqdv2%%k+V4v|j{2)@(T_az16m0g^3V@xC3$wS zfDS<`$VWf&?P4Jn=EJw)CR3)3HrChj$K>r67+8=`UmZ4N?Pi`H-OCu8>k)O4oZE% zA$C&T1L#`?`u2cb?4tAvhxipWApA9TAlywEl@8HJjg{|Gu(uyR@OcSps$Di#h_~s& z@*LTUx3nJE(eg{4_K(4ZIB#0DW_eTD$|}Km4BFTFmZprA2ZjDTc8ERQ77q)Q?8R2T z+K1$a@zuf)g?dqgcO>m!w$;GzhF;h*`Xf^;+lG|ql`Q4IB9|l8udUpGBK#`BR$ekk z;pYbzkG$KdY)yAjN-Nf^mbEXoImLyRB5bobkMi}lX~VK)(KKakbO>@pcRR5g3Akz+ zY2&XG$K1Z7UL3_K+!$p8@B^KT;uluF8UeQ9H)wn^RIcBU@9y3s_CV$oe)q7>sl-UqK6f1N2YlUe&r`i<^v_bLI5ry%>@d91pvR}@{W2jz#G(G0F}Tp-mhc4{7%g`N?H_(N?-(#-s0;x054d}|TZZ^2N6PWWd|5*O9 z&VxT0@B$_PTz4YS58x)Vi@I+vjcC)}z#eykkPry)m!$+cus6pr9uk||DP*7BerJKLK!A z?6WR_9fqBNoq-*M%VK9?=V5zxrez#e384bu31;td0i0ROz{W6CJWi|71)WEkJI;+^ z57W}v>)3VI0ILDb^Ei$hz;@gS_S7=IVYt;=Bsbzw;1OU0@GwBY7GN{55!eK9#ccB! zpjD`i0K3sIfhU2dfJRDsZcw+a`yt}`<}8&yH?V2zb16Dm`(Lg7EYgWtF_tJxf<$jU zUl^zTz25ZUrT64brylJoBH=Z`7@=o``hRS>Dfxd2*GRmc7QUDv3_UUOa7$Mmy>>v>Sq${SftWb$FM4_HxZ5x8y1Pm#AsPip+JE-& zi#r!xnE%2|wQNo~NfTa@&D!tkvt1@Vk@iu^NiPv)i5X^z!SYM1UXsOadh#VXQ2W{a zlsW3~TkSd1JywIf>9;SL;f7Pd&TzjK@Ixe|}QBId)*X?jBDHzGNSi&D#I= zcUR}9ML&MI#go3CG7idkKbQ|I?Qi{shMqyE2DeZ2Se>J%56bb{@BQLAJMO%*`B17S zT{{3Ux6gM5pZ?IHrl7`aZ^3Ne;T4{gk=-e! z*<{uZAyD$CcNJ~eR^u@!rUlJ%oOWp8>{qV-RnKISCtW+%(AC!(-Ygz{-IKD5jyB6W zy&qj_j?wkvaC~2ed#tbnroH zXxA@CjXvcu8|64!IZQV!7fM`ZIwPi2KqFWs`Y0)(brTT*HcA zj)_lQ@~y{g4pqM_$7wH;1szo`FWZ5!%H0`diIpVn%tC^*F#lGA#o{I0OM>)1oqt)5 z*UmW9uarh+?bu%AN!Lz6tgJour$04+Q|U>G4yC}OCbM>I;@QZYS1#6+NFIZHns`)> z(~en06b#ZkH|T%wN!JcythjLJtp^sqS>Q=IM)gN!b15GCctE>e?C5uSlk2HwbSJ?Q z6K{!Q=%AD|RGbX~Qy@VLL87v#q% z@}z%%mb9Z6-M5UH;=AS&1`Ni^)l3b?Wbpi{G<9zi3mESMymxX2EmGf zc8J4gRNA{fBW@%rt%>HWY$W5y)hsN<8O zAWoVXNj*-O%-X39=dx#xe(C?-vzkGaw2@Lz$k;}qt5gP8tfze~GJYU# zM6BABBlOCNG2%QKS~A`Bng4ZtKQ2fqg08j@NQnu6oWpUq9iVh7k?fDwf8&{{^UC4W!6r-%xe4G za^Lp8wdxphACxx!gBxm-#Z$^%*GlTA3yG)gr%dtMerv(jH+@#tjDG?J;t`16OWGNl z(}BHj*SGta)T+442y`8iL>M+PJzM5gWwN(-X|wBfXD)=tLE zY8d*-j(0!H@)9u^Uo=dbPc5gpJ@3LwJ6B`wxaE52b$P1C>KOT)k>j;it>!gzBFHY&bn8A|oPI sAwqe5vn-ysY*ut4yKZn*Rq(9nq#ub9i*jh;IWtB6wR6*&*MhA73qu*dQ2+n{ delta 10228 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 diff --git a/package.json b/package.json index 623ede0..8859855 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@tauri-apps/plugin-upload": "~2", "react": "^18.3.1", "react-dom": "^18.3.1", + "sonner": "^2.0.7", "tailwindcss": "^4.0.2", "tauri-plugin-macos-permissions-api": "^2.0.4", "zod": "^3.24.4" diff --git a/src/App.tsx b/src/App.tsx index e3c80e6..fbd1a45 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,6 +6,7 @@ import Footer from "./components/footer"; import HandyTextLogo from "./components/icons/HandyTextLogo"; import Onboarding from "./components/onboarding"; import { Settings } from "./components/settings/Settings"; +import { Toaster } from "sonner"; function App() { const [showOnboarding, setShowOnboarding] = useState(null); @@ -43,6 +44,7 @@ function App() { return (
+
diff --git a/src/components/settings/HandyShortcut.tsx b/src/components/settings/HandyShortcut.tsx index b4ebd96..2501ab0 100644 --- a/src/components/settings/HandyShortcut.tsx +++ b/src/components/settings/HandyShortcut.tsx @@ -11,6 +11,7 @@ import ResetIcon from "../icons/ResetIcon"; import { SettingContainer } from "../ui/SettingContainer"; import { useSettings } from "../../hooks/useSettings"; import { invoke } from "@tauri-apps/api/core"; +import { toast } from "sonner"; interface HandyShortcutProps { descriptionMode?: "inline" | "tooltip"; @@ -38,7 +39,7 @@ export const HandyShortcut: React.FC = ({ useEffect(() => { const detectOsType = async () => { try { - const detectedType = await type(); + const detectedType = type(); let normalizedType: OSType; switch (detectedType) { @@ -75,8 +76,18 @@ export const HandyShortcut: React.FC = ({ const handleKeyDown = async (e: KeyboardEvent) => { if (e.repeat) return; // ignore auto-repeat if (e.key === "Escape") { - // Cancel recording - if (editingShortcutId) { + // Cancel recording and restore original binding + if (editingShortcutId && originalBinding) { + try { + await updateBinding(editingShortcutId, originalBinding); + await invoke("resume_binding", { id: editingShortcutId }).catch( + console.error, + ); + } catch (error) { + console.error("Failed to restore original binding:", error); + toast.error("Failed to restore original shortcut"); + } + } else if (editingShortcutId) { await invoke("resume_binding", { id: editingShortcutId }).catch( console.error, ); @@ -129,6 +140,20 @@ export const HandyShortcut: React.FC = ({ ); } catch (error) { console.error("Failed to change binding:", error); + toast.error(`Failed to set shortcut: ${error}`); + + // Reset to original binding on error + if (originalBinding) { + try { + await updateBinding(editingShortcutId, originalBinding); + await invoke("resume_binding", { id: editingShortcutId }).catch( + console.error, + ); + } catch (resetError) { + console.error("Failed to reset binding:", resetError); + toast.error("Failed to reset shortcut to original value"); + } + } } // Exit editing mode and reset states @@ -141,11 +166,21 @@ export const HandyShortcut: React.FC = ({ }; // Add click outside handler - const handleClickOutside = (e: MouseEvent) => { + const handleClickOutside = async (e: MouseEvent) => { const activeElement = shortcutRefs.current.get(editingShortcutId); if (activeElement && !activeElement.contains(e.target as Node)) { - // Cancel shortcut recording - the hook will handle rollback - if (editingShortcutId) { + // Cancel shortcut recording and restore original binding + if (editingShortcutId && originalBinding) { + try { + await updateBinding(editingShortcutId, originalBinding); + await invoke("resume_binding", { id: editingShortcutId }).catch( + console.error, + ); + } catch (error) { + console.error("Failed to restore original binding:", error); + toast.error("Failed to restore original shortcut"); + } + } else if (editingShortcutId) { invoke("resume_binding", { id: editingShortcutId }).catch( console.error, );