@@ -3,7 +3,8 @@ import { listen } from "@tauri-apps/api/event";
33import { syncAllKeyboardSettings } from "../keyboard" ;
44import { syncAllMouseSettings } from "../mouse" ;
55import { notify } from "../notifications" ;
6- import { updateTabStates } from "../ui" ;
6+ import { getSelectedMode , updateTabStates } from "../ui" ;
7+ import type { AppMode } from "../ui" ;
78
89type RunningPayload = {
910 running ?: boolean ;
@@ -16,6 +17,9 @@ type MacroStatusPayload = {
1617
1718type SupportedTab = "mouse" | "keyboard" | "macro" ;
1819
20+ let runningMode : SupportedTab | null = null ;
21+ let isToggling = false ;
22+
1923function getStartButton ( ) {
2024 return document . getElementById ( "start-btn" ) ;
2125}
@@ -42,14 +46,7 @@ function setStartButtonState(isRunning: boolean) {
4246}
4347
4448function getActiveTab ( ) : SupportedTab {
45- const activeTab = document . querySelector < HTMLElement > ( ".mode-tabs .tab.active" ) ;
46- const tab = activeTab ?. dataset . tab ;
47-
48- if ( tab === "keyboard" || tab === "macro" ) {
49- return tab ;
50- }
51-
52- return "mouse" ;
49+ return getSelectedMode ( ) ;
5350}
5451
5552function getMouseIntervalMs ( ) : number {
@@ -77,50 +74,69 @@ function showTimingWarningModal() {
7774}
7875
7976async function toggleMouseClicker ( ) {
80- await invoke ( "toggle_clicker" ) ;
77+ return invoke < boolean > ( "toggle_clicker" ) ;
78+ }
79+
80+ function rememberRunningMode ( mode : AppMode , isRunning : boolean ) {
81+ if ( isRunning ) {
82+ runningMode = mode ;
83+ return ;
84+ }
85+
86+ if ( runningMode === mode ) {
87+ runningMode = null ;
88+ }
8189}
8290
8391async function handleStartButtonClick ( ) {
8492 const startButton = getStartButton ( ) ;
85- if ( ! startButton ) {
93+ if ( ! startButton || isToggling ) {
8694 return ;
8795 }
8896
89- const activeTab = getActiveTab ( ) ;
90- const isAlreadyRunning = startButton . classList . contains ( "running" ) ;
97+ isToggling = true ;
98+ try {
99+ const isAlreadyRunning = startButton . classList . contains ( "running" ) ;
100+ const activeTab = isAlreadyRunning && runningMode ? runningMode : getActiveTab ( ) ;
91101
92- if ( activeTab === "keyboard" ) {
93- if ( ! isAlreadyRunning ) {
94- await syncAllKeyboardSettings ( ) ;
95- }
102+ if ( activeTab === "keyboard" ) {
103+ if ( ! isAlreadyRunning ) {
104+ await syncAllKeyboardSettings ( ) ;
105+ }
96106
97- const isRunning = await invoke < boolean > ( "toggle_keyboard_clicker" ) ;
98- setStartButtonState ( Boolean ( isRunning ) ) ;
99- updateTabStates ( ) ;
100- return ;
101- }
107+ const isRunning = await invoke < boolean > ( "toggle_keyboard_clicker" ) ;
108+ rememberRunningMode ( "keyboard" , Boolean ( isRunning ) ) ;
109+ setStartButtonState ( Boolean ( isRunning ) ) ;
110+ updateTabStates ( ) ;
111+ return ;
112+ }
102113
103- if ( activeTab === "macro" ) {
104- try {
114+ if ( activeTab === "macro" ) {
105115 const isRunning = await invoke < boolean > ( "toggle_macro_player" ) ;
116+ rememberRunningMode ( "macro" , Boolean ( isRunning ) ) ;
106117 setStartButtonState ( Boolean ( isRunning ) ) ;
107- } catch ( error ) {
108- console . error ( "Failed to toggle macro player" , error ) ;
109- notify ( error instanceof Error ? error . message : String ( error ) , "error" , 3200 ) ;
118+ updateTabStates ( ) ;
119+ return ;
110120 }
111121
112- updateTabStates ( ) ;
113- return ;
114- }
122+ if ( ! isAlreadyRunning && getMouseIntervalMs ( ) <= 3 ) {
123+ showTimingWarningModal ( ) ;
124+ return ;
125+ }
115126
116- if ( ! isAlreadyRunning && getMouseIntervalMs ( ) <= 3 ) {
117- showTimingWarningModal ( ) ;
118- return ;
127+ if ( ! isAlreadyRunning ) {
128+ await syncAllMouseSettings ( ) ;
129+ }
130+ const isRunning = await toggleMouseClicker ( ) ;
131+ rememberRunningMode ( "mouse" , Boolean ( isRunning ) ) ;
132+ setStartButtonState ( Boolean ( isRunning ) ) ;
133+ updateTabStates ( ) ;
134+ } catch ( error ) {
135+ console . error ( "Failed to toggle selected mode" , error ) ;
136+ notify ( error instanceof Error ? error . message : String ( error ) , "error" , 3200 ) ;
137+ } finally {
138+ isToggling = false ;
119139 }
120-
121- await syncAllMouseSettings ( ) ;
122- await toggleMouseClicker ( ) ;
123- updateTabStates ( ) ;
124140}
125141
126142export function initStartStopControls ( ) {
@@ -132,18 +148,24 @@ export function initStartStopControls() {
132148 }
133149
134150 void listen < RunningPayload > ( "status-changed" , ( event ) => {
135- setStartButtonState ( Boolean ( event . payload . running ) ) ;
151+ const isRunning = Boolean ( event . payload . running ) ;
152+ rememberRunningMode ( "mouse" , isRunning ) ;
153+ setStartButtonState ( isRunning ) ;
136154 updateTabStates ( ) ;
137155 } ) ;
138156
139157 void listen < RunningPayload > ( "keyboard-status-changed" , ( event ) => {
140- setStartButtonState ( Boolean ( event . payload . running ) ) ;
158+ const isRunning = Boolean ( event . payload . running ) ;
159+ rememberRunningMode ( "keyboard" , isRunning ) ;
160+ setStartButtonState ( isRunning ) ;
141161 updateTabStates ( ) ;
142162 } ) ;
143163
144164 void listen < MacroStatusPayload > ( "macro-status-changed" , ( event ) => {
145165 const state = String ( event . payload ?. state || "stopped" ) ;
146- setStartButtonState ( state === "playing" ) ;
166+ const isRunning = state === "playing" ;
167+ rememberRunningMode ( "macro" , isRunning ) ;
168+ setStartButtonState ( isRunning ) ;
147169 updateTabStates ( ) ;
148170
149171 if ( state === "error" && event . payload ?. error ) {
0 commit comments