()
| 140 | } |
| 141 | |
| 142 | export default function ProcessManager() { |
| 143 | const [processes, setProcesses] = useState<ProcessInfo[]>([]); |
| 144 | const [search, setSearch] = useState(""); |
| 145 | const [icons, setIcons] = useState<Record<number, string>>({}); |
| 146 | const [speedMap, setSpeedMap] = useState<Map<number, SpeedState>>(new Map()); |
| 147 | const [selectedPid, setSelectedPid] = useState<number | null>(null); |
| 148 | const { settings } = useSettings(); |
| 149 | const { speed, setSpeed, commitSpeed } = useSpeed(); |
| 150 | const { notify } = useSnackbar(); |
| 151 | const { t } = useTranslation(); |
| 152 | |
| 153 | const gears = useMemo(() => settings |
| 154 | ? [1, 2, 3, 4, 5].map(i => (settings[`gear${i}Speed` as keyof typeof settings] as number) || 1) |
| 155 | : [1, 2, 5, 10, 100], |
| 156 | [settings]); |
| 157 | |
| 158 | // Derive enabled set for UI |
| 159 | const enabled = useMemo(() => { |
| 160 | const s = new Set<number>(); |
| 161 | for (const [pid, st] of speedMap) { if (st.enabled) s.add(pid); } |
| 162 | return s; |
| 163 | }, [speedMap]); |
| 164 | |
| 165 | // Toggle — optimistic update with rollback on failure |
| 166 | async function toggle(pid: number, arch: string) { |
| 167 | const cur = speedMap.get(pid); |
| 168 | const wasOn = cur?.enabled ?? false; |
| 169 | const wasInjected = cur?.injected ?? false; |
| 170 | |
| 171 | if (!wasOn) { |
| 172 | // Turning ON |
| 173 | if (!wasInjected) { |
| 174 | // First time inject |
| 175 | setSpeedMap(prev => { const n = new Map(prev); n.set(pid, { injected: true, enabled: true, arch }); return n; }); |
| 176 | const ok = await invoke<boolean>("bridge_inject", { pid, arch }).catch((e) => { console.error("[toggle] bridge_inject error:", e); return false; }); |
| 177 | console.log("[toggle] bridge_inject result:", ok); |
| 178 | if (!ok) { |
| 179 | setSpeedMap(prev => { const n = new Map(prev); n.delete(pid); return n; }); |
| 180 | notify(t("process.injectFail"), "error"); |
| 181 | } |
| 182 | } else { |
| 183 | // Already injected — re-enable |
| 184 | setSpeedMap(prev => { const n = new Map(prev); n.set(pid, { ...cur!, enabled: true }); return n; }); |
| 185 | const ok = await invoke<boolean>("bridge_enable", { pid, arch }).catch(() => false); |
| 186 | if (!ok) { |
| 187 | setSpeedMap(prev => { const n = new Map(prev); n.set(pid, cur!); return n; }); |
| 188 | notify(t("process.enableFail"), "error"); |
| 189 | } |
| 190 | } |
| 191 | } else { |
| 192 | // Turning OFF |
| 193 | setSpeedMap(prev => { const n = new Map(prev); n.set(pid, { ...cur!, enabled: false }); return n; }); |
| 194 | const ok = await invoke<boolean>("bridge_disable", { pid, arch }).catch(() => false); |
| 195 | if (!ok) { |
| 196 | setSpeedMap(prev => { const n = new Map(prev); n.set(pid, cur!); return n; }); |
| 197 | notify(t("process.disableFail"), "error"); |
| 198 | } |
| 199 | } |
nothing calls this directly
no test coverage detected