Skip to content

Commit

Permalink
update: Settings page now functional
Browse files Browse the repository at this point in the history
  • Loading branch information
rajabilal555 committed Jul 17, 2023
1 parent 8884390 commit 657d8ab
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 41 deletions.
6 changes: 6 additions & 0 deletions global/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//These are the global types i will be using in both processes

type SettingsStoreType = {
interval: number;
message: string;
};
22 changes: 8 additions & 14 deletions main/background.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Menu, Notification, Tray, app } from "electron";
import log from "electron-log";
import { Menu, Tray, app } from "electron";
import serve from "electron-serve";
import { createWindow, getAppPath } from "./helpers";
import NotificationHandler from "./helpers/notificationHandler";
import { loadIpcHandlers } from "./ipc";
const isProd: boolean = process.env.NODE_ENV === "production";

if (isProd) {
Expand All @@ -13,9 +14,6 @@ if (isProd) {
(async () => {
await app.whenReady();
const iconpath = getAppPath("resources/icon.ico");
console.log(iconpath);
log.info("Log from the main process");
log.info(`IconPath: ${iconpath}`);
const mainWindow = createWindow("main", {
width: 600,
height: 700,
Expand All @@ -41,24 +39,20 @@ if (isProd) {
mainWindow.show();
});
tray.setContextMenu(contextMenu);
//* Load the IPC Handlers
loadIpcHandlers();
//* Initialize the Notification handler
NotificationHandler.init();

//* Load our Page
if (isProd) {
await mainWindow.loadURL("app://./home.html");
} else {
const port = process.argv[2];
await mainWindow.loadURL(`http://localhost:${port}/home`);
// mainWindow.webContents.openDevTools();
}
setInterval(showNotification, 120000);
})();
const showNotification = () => {
const NOTIFICATION_TITLE = "Look Away 🔔";
const NOTIFICATION_BODY = "Avert yer eyeees!!!!";
new Notification({
title: NOTIFICATION_TITLE,
body: NOTIFICATION_BODY,
}).show();
};
app.on("window-all-closed", () => {
app.quit();
});
96 changes: 96 additions & 0 deletions main/helpers/notificationHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Notification } from "electron";
import { getStoredNumber, getStoredString } from "./storageHelper";

class NotificationHandler {
private static instance: NotificationHandler | null = null;
private intervalId: NodeJS.Timeout | null;

// Interval in seconds
private interval: number;
private message: string;

constructor(interval: number, message?: string) {
this.intervalId = null;
this.interval = interval;
this.message = message;
}

static init(): NotificationHandler {
if (!NotificationHandler.instance) {
const interval = getStoredNumber("interval", 120);
const message = getStoredString("message", "Time for a little break");
NotificationHandler.instance = new NotificationHandler(interval, message);
}
NotificationHandler.instance.start();
return NotificationHandler.instance;
}

static getInstance(): NotificationHandler {
if (!NotificationHandler.instance) {
throw new Error(
"NotificationHandler has not been initialized please use the init() function first"
);
}
return NotificationHandler.instance;
}

sendNotification(): void {
const NOTIFICATION_TITLE = "Look Away 🔔";
const NOTIFICATION_BODY = this.message;
const notif = new Notification({
title: NOTIFICATION_TITLE,
body: NOTIFICATION_BODY,
});
notif.show();
//? remove the notification after 20 seconds to stop them from pilling up
setTimeout(() => notif.close(), 20000);
}

updateTime(newInterval: number): void {
this.interval = newInterval;
if (this.isRunning()) {
this.restart();
}
}

update(newInterval: number, message: string): void {
this.interval = newInterval;
this.message = message;
if (this.isRunning()) {
this.restart();
}
}

updateMessage(message: string): void {
this.message = message;
if (this.isRunning()) {
this.restart();
}
}

start(): void {
if (!this.isRunning()) {
this.intervalId = setInterval(() => {
this.sendNotification();
}, this.interval * 1000);
}
}

stop(): void {
if (this.isRunning()) {
clearInterval(this.intervalId!);
this.intervalId = null;
}
}

isRunning(): boolean {
return this.intervalId !== null;
}

private restart(): void {
this.stop();
this.start();
}
}

export default NotificationHandler;
54 changes: 54 additions & 0 deletions main/helpers/storageHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Store from "electron-store";

export const settingsStore = new Store<SettingsStoreType>({
schema: {
interval: {
type: "number",
minimum: 1,
},
message: {
type: "string",
},
},
defaults: {
interval: 120,
message: "Time for a little break",
},
});

export function getStoredNumber(key: string, defaultValue?: number): number {
try {
return settingsStore.get(key, defaultValue);
} catch (error) {
console.error(`Error retrieving value for key "${key}":`, error);
throw error;
}
}

export function setStoredNumber(key: string, value: number): void {
try {
settingsStore.set(key, value);
} catch (error) {
console.error(`Error saving value for key "${key}":`, error);
throw error;
}
}

export function getStoredString(key: string, defaultValue?: string): string {
try {
const val = settingsStore.get(key, defaultValue);
return val;
} catch (error) {
console.error(`Error retrieving value for key "${key}":`, error);
throw error;
}
}

export function setStoredString(key: string, value: string): void {
try {
settingsStore.set(key, value);
} catch (error) {
console.error(`Error saving value for key "${key}":`, error);
throw error;
}
}
28 changes: 28 additions & 0 deletions main/ipc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ipcMain } from "electron";
import NotificationHandler from "./helpers/notificationHandler";
import { settingsStore } from "./helpers/storageHelper";

export function loadIpcHandlers() {
ipcMain.handle("getSettingValue", (event, key: string) => {
return settingsStore.get(key);
});

ipcMain.handle("updateSettings", (event, settings: SettingsStoreType) => {
try {
settingsStore.set("interval", settings.interval);
settingsStore.set("message", settings.message);
const notificationHandler = NotificationHandler.getInstance();
notificationHandler.update(settings.interval, settings.message);
console.log(
`Set interval to ${settings.interval} and message to ${settings.message}`
);
return true;
} catch (error) {
return false;
}
});

ipcMain.on("show:testNotification", (event, arg) => {
NotificationHandler.getInstance().sendNotification();
});
}
19 changes: 15 additions & 4 deletions renderer/pages/home.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { Layout, Result, Row } from "antd";
import { ipcRenderer } from "electron";
import Head from "next/head";
import Link from "next/link";
import React from "react";
import React, { useEffect, useState } from "react";

const { Header, Content } = Layout;

const ipc = ipcRenderer || false;

function Home() {
const [intervalSetting, setIntervalSetting] = useState<number>();

useEffect(() => {
if (ipc) {
ipc
.invoke("getSettingValue", "interval")
.then((v) => setIntervalSetting(v));
}
}, []);

return (
<React.Fragment>
{/* @ts-ignore */}
Expand All @@ -28,9 +41,7 @@ function Home() {
title="LAR"
subTitle="Look away Reminder"
/>
<p>
Will show a notification every 2 minutes or 120 seconds by default.
</p>
<p>We will show a notification every {intervalSetting} seconds.</p>
</div>
</Content>
</React.Fragment>
Expand Down
Loading

0 comments on commit 657d8ab

Please sign in to comment.