Add watcher status and additional typing.

This commit is contained in:
Patrick Fic
2025-03-21 11:28:30 -07:00
parent 6da5822197
commit 14e7c64eab
19 changed files with 385 additions and 81 deletions

View File

@@ -1,16 +1,50 @@
import { Button } from "antd";
import {
CheckCircleOutlined,
ExclamationCircleOutlined,
} from "@ant-design/icons";
import {
selectWatcherError,
selectWatcherStatus,
} from "@renderer/redux/app.slice";
import { useAppDispatch, useAppSelector } from "@renderer/redux/reduxHooks";
import { Button, Space } from "antd";
import { useTranslation } from "react-i18next";
import ipcTypes from "../../../../util/ipcTypes.json";
const SettingsWatcher: React.FC = () => {
const { t } = useTranslation();
const isWatcherStarted = useAppSelector(selectWatcherStatus);
const watcherError = useAppSelector(selectWatcherError);
const dispatch = useAppDispatch();
const handleStart = (): void => {
window.electron.ipcRenderer.send(ipcTypes.toMain.watcher.start);
};
const handleStop = (): void => {
window.electron.ipcRenderer.send(ipcTypes.toMain.watcher.stop);
};
return (
<Button onClick={handleStart}>{t("settings.actions.startwatcher")}</Button>
<>
<Button onClick={handleStart}>
{t("settings.actions.startwatcher")}
</Button>
<Button onClick={handleStop}>{t("settings.actions.stopwatcher")}</Button>
{isWatcherStarted}
{watcherError}
{isWatcherStarted ? (
<Space>
<CheckCircleOutlined style={{ color: "green" }} />
{t("settings.labels.started")}
</Space>
) : (
<Space>
<ExclamationCircleOutlined style={{ color: "tomato" }} />
{t("settings.labels.stopped")}
</Space>
)}
</>
);
};
export default SettingsWatcher;

View File

@@ -1,46 +1,58 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import log from "electron-log/renderer";
import type { RootState } from "./redux-store";
// Define a type for the slice state
interface AppState {
value: number;
watcher: {
started: boolean;
error: string | null;
};
}
// Define the initial state using that type
const initialState: AppState = {
value: 0,
watcher: {
started: false,
error: null,
},
};
export const appSlice = createSlice({
name: "counter",
name: "app",
// `createSlice` will infer the state type from the `initialState` argument
initialState,
reducers: {
increment: (state) => {
state.value += 1;
watcherStarted: (state) => {
state.watcher.started = true;
},
decrement: (state) => {
state.value -= 1;
watcherStopped: (state) => {
state.watcher.started = false;
},
// Use the PayloadAction type to declare the contents of `action.payload`
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
watcherError: (state, action: PayloadAction<string>) => {
state.watcher.error = action.payload;
state.watcher.started = false;
log.error("[Redux] AppSlice: Watcher Error", action.payload);
},
},
});
export const { increment, decrement, incrementByAmount } = appSlice.actions;
export const { watcherError, watcherStarted, watcherStopped } =
appSlice.actions;
// Other code such as selectors can use the imported `RootState` type
export const selectCount = (state: RootState): number => state.app.value;
export const selectWatcherStatus = (state: RootState): boolean =>
state.app.watcher.started;
export const selectWatcherError = (state: RootState): string | null =>
state.app.watcher.error;
//Async Functions - Thunks
// Define a thunk that dispatches those action creators
const fetchUsers = () => async (dispatch) => {
dispatch(increment());
//dispatch(watcherStarted());
//Some sort of async action.
dispatch(incrementByAmount(100));
// dispatch(incrementByAmount(100));
};
export default appSlice.reducer;

View File

@@ -1,9 +1,10 @@
import type { TypedUseSelectorHook } from "react-redux";
import { useDispatch, useSelector, useStore } from "react-redux";
import type { AppDispatch, AppStore, RootState } from "./redux-store";
import store from "./redux-store";
//Use these custom hooks to access the Redux store from your component with type safety.
export const useAppDispatch: () => AppDispatch = useDispatch;
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = useDispatch.withTypes<AppDispatch>(); // Ex
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export const useAppStore: () => AppStore = useStore;

View File

@@ -1,8 +1,15 @@
//Set up all of the IPC handlers.
import {
watcherError,
watcherStarted,
watcherStopped,
} from "@renderer/redux/app.slice";
import store from "@renderer/redux/redux-store";
import ipcTypes from "../../../util/ipcTypes.json";
import { auth } from "./firebase";
const ipcRenderer = window.electron.ipcRenderer;
const dispatch = store.dispatch;
ipcRenderer.on(
ipcTypes.toRenderer.test,
@@ -19,3 +26,29 @@ ipcRenderer.on(
ipcRenderer.send(ipcTypes.toMain.user.getTokenResponse, token);
}
);
ipcRenderer.on(
ipcTypes.toRenderer.watcher.started,
(event: Electron.IpcRendererEvent, arg) => {
console.log("Watcher has started");
console.log(arg);
dispatch(watcherStarted());
}
);
ipcRenderer.on(
ipcTypes.toRenderer.watcher.stopped,
(event: Electron.IpcRendererEvent, arg) => {
console.log("Watcher has stopped");
console.log(arg);
dispatch(watcherStopped());
}
);
ipcRenderer.on(
ipcTypes.toRenderer.watcher.error,
(event: Electron.IpcRendererEvent, error: string) => {
console.log("Watcher has encountered an error");
console.log(error);
dispatch(watcherError(error));
}
);