Skip to content

Commit

Permalink
Add support for non-official instances, closes #1
Browse files Browse the repository at this point in the history
  • Loading branch information
xdpirate committed Aug 3, 2023
1 parent eb68758 commit fc5a2a9
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 58 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Dead simple Electron wrapper for the ntfy web app.
## Features
* Tray icon, click it to hide/show the main window
* Native notifications
* Support for non-official ntfy instances

## Command-line arguments
`--hidden`<br />
Expand Down
121 changes: 78 additions & 43 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,94 @@
const { app, BrowserWindow, Tray } = require('electron');
const { app, BrowserWindow, Tray, Menu, MenuItem } = require('electron');
const process = require('process');
const path = require('path');
const Store = require('./store.js');

console.log(process.argv);

let win, tray;
let winHidden = 0;
let appIconLoc = app.getAppPath() + "/ntfy.png";

function ready() {
win = new BrowserWindow({
width: 1280,
height: 720,
icon: appIconLoc,
title: "ntfy-electron"
});

win.menuBarVisible = false;
win.loadURL("https://ntfy.sh/app");

win.on('closed', () => {
win = null;
});

win.webContents.on('new-window', (event, url) => {
event.preventDefault();
win.loadURL(url);
});

tray = new Tray(appIconLoc);
tray.setToolTip("ntfy-electron | click to hide/show main window");

tray.on("click", function() {
if(winHidden) {
winHidden = 0;
win.show();
} else {
winHidden = 1;
win.hide();
const store = new Store({
configName: 'prefs',
defaults: {
instanceURL: "https://ntfy.sh/app"
}
});
});

win.on("page-title-updated", (event) => {
event.preventDefault();
});
const prompt = require("custom-electron-prompt");

console.log("process.argv[0] == " + process.argv[0]);
console.log("process.argv[1] == " + process.argv[1]);
console.log("process.argv[2] == " + process.argv[2]);
Menu.setApplicationMenu(Menu.buildFromTemplate([
{
label: 'Options',
submenu: [
{
label: "Set ntfy instance URL",
click: function() {
prompt({
title: "ntfy-electron",
label: 'ntfy instance URL:',
value: store.get("instanceURL"),
inputAttrs: {
type: 'url'
},
type: 'input'
})
.then((response) => {
if((response !== null)) {
store.set("instanceURL", response);
win.loadURL(response);
}
})
.catch(console.error);
}
}
]
}
]));

for(i = 0; i < process.argv.length; i++) {
if(process.argv[i] == "--hidden") {
winHidden = 1;
win.hide();
function ready() {
win = new BrowserWindow({
width: 1280,
height: 720,
icon: appIconLoc,
title: "ntfy-electron"
});

win.loadURL(store.get("instanceURL"));

win.on('closed', () => {
win = null;
});

win.webContents.on('new-window', (event, url) => {
event.preventDefault();
win.loadURL(url);
});

tray = new Tray(appIconLoc);
tray.setToolTip("ntfy-electron | click to hide/show main window");

tray.on("click", function() {
if(winHidden) {
winHidden = 0;
win.show();
} else {
winHidden = 1;
win.hide();
}
});

win.on("page-title-updated", (event) => {
event.preventDefault();
});

for(i = 0; i < process.argv.length; i++) {
if(process.argv[i] == "--hidden") {
winHidden = 1;
win.hide();
}
}
}
}

app.on('ready', ready);
43 changes: 29 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ntfy-electron",
"version": "1.0.1",
"version": "1.0.2",
"description": "Electron wrapper for ntfy web app",
"main": "index.js",
"scripts": {
Expand All @@ -9,6 +9,7 @@
"author": "xdpirate",
"license": "GPL-3.0-or-later",
"dependencies": {
"custom-electron-prompt": "^1.5.7",
"electron": "^24.1.3"
}
}
46 changes: 46 additions & 0 deletions store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Respectfully stolen from Cameron Nokes @ Medium:
// https://medium.com/cameron-nokes/how-to-store-user-data-in-electron-3ba6bf66bc1e
const electron = require('electron');
const path = require('path');
const fs = require('fs');

class Store {
constructor(opts) {
// Renderer process has to get `app` module via `remote`, whereas the main process can get it directly
// app.getPath('userData') will return a string of the user's app data directory path.
const userDataPath = (electron.app || electron.remote.app).getPath('userData');
// We'll use the `configName` property to set the file name and path.join to bring it all together as a string
this.path = path.join(userDataPath, opts.configName + '.json');

this.data = parseDataFile(this.path, opts.defaults);
}

// This will just return the property on the `data` object
get(key) {
return this.data[key];
}

// ...and this will set it
set(key, val) {
this.data[key] = val;
// Wait, I thought using the node.js' synchronous APIs was bad form?
// We're not writing a server so there's not nearly the same IO demand on the process
// Also if we used an async API and our app was quit before the asynchronous write had a chance to complete,
// we might lose that data. Note that in a real app, we would try/catch this.
fs.writeFileSync(this.path, JSON.stringify(this.data));
}
}

function parseDataFile(filePath, defaults) {
// We'll try/catch it in case the file doesn't exist yet, which will be the case on the first application run.
// `fs.readFileSync` will return a JSON string which we then parse into a Javascript object
try {
return JSON.parse(fs.readFileSync(filePath));
} catch(error) {
// if there was some kind of error, return the passed in defaults instead.
return defaults;
}
}

// expose the class
module.exports = Store;

0 comments on commit fc5a2a9

Please sign in to comment.