Skip to content

Commit

Permalink
Merge pull request #8 from richrace/add-debug-menu
Browse files Browse the repository at this point in the history
Add debug menu
  • Loading branch information
richrace authored Aug 27, 2023
2 parents 9b396d2 + 7cb241c commit 355fc11
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 82 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"typescript": "^5.0.4"
},
"dependencies": {
"arctis-usb-finder": "0.0.14",
"arctis-usb-finder": "^0.0.15",
"electron-squirrel-startup": "^1.0.0"
}
}
37 changes: 37 additions & 0 deletions src/headphone_view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import SimpleHeadphone from 'arctis-usb-finder/dist/interfaces/simple_headphone';

import { MenuItem } from 'electron';

function exportView(mainTray: any, headphone: SimpleHeadphone) {
if (!headphone.isConnected) {
mainTray.setTitle('');
return new MenuItem({ label: `${headphone.modelName} - Not connected`, type: 'normal' });
}

let percentage = headphone.batteryPercent > 100 ? 100 : headphone.batteryPercent;
percentage = percentage < 0 ? 0 : percentage;

let text = `${headphone.modelName} - ${percentage}%`;

// Set the Tool Tip and title so we don't have to click to see a percentage
mainTray.setToolTip(`${text}`);
mainTray.setTitle(` ${percentage}%`);

if (headphone.isCharging) {
text += ' 🔋 ';
}

if (headphone.isDischarging) {
text += ' 🪫 ';
}

if (headphone.isMuted) {
text += ' 🔇 ';
} else {
text += ' 🔊 ';
}

return new MenuItem({ label: text });
}

export default exportView;
18 changes: 18 additions & 0 deletions src/load_headphones.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getHeadphones, refreshHeadphones } from 'arctis-usb-finder';
import SimpleHeadphone from 'arctis-usb-finder/dist/interfaces/simple_headphone';

let cachedHeadphones: SimpleHeadphone[] = undefined;

function loadHeadphones(force: boolean = false): SimpleHeadphone[] {
if (force || cachedHeadphones === undefined) {
cachedHeadphones = getHeadphones();
console.log('forced', cachedHeadphones);
} else {
cachedHeadphones = refreshHeadphones(cachedHeadphones);
console.log('not forced', cachedHeadphones);
}

return cachedHeadphones;
}

export default loadHeadphones;
7 changes: 4 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const { createTray } = require('./tray');
import { app, BrowserWindow } from 'electron';
import createTray from './tray';

import path = require('path');

if (require('electron-squirrel-startup')) app.quit();

Expand Down
64 changes: 64 additions & 0 deletions src/menu_items/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import ProbeResult from 'arctis-usb-finder/dist/interfaces/probe_result';
import UsbDevice from 'arctis-usb-finder/dist/interfaces/usb_device';
import Probe from 'arctis-usb-finder/dist/use_cases/probe';

import { MenuItem } from 'electron';

function debugMenu(): MenuItem {
const probe = new Probe();
const steelseriesHeadsets = probe.steelseriesHeadsets();
const foundHeadphones = probe.testUnknownHeadset(steelseriesHeadsets);

let probeMenuItems = [{ label: 'No headphones found' }];
let foundButNotConnected = [{ label: 'No headphones found' }];

const filteredSteelseriesHeadsets = steelseriesHeadsets.filter((headset) => {
return foundHeadphones.some((foundHeadphone) => {
console.log('comparing', headset.productId !== foundHeadphone.device.productId);
return headset.productId !== foundHeadphone.device.productId;
});
});

if (filteredSteelseriesHeadsets.length > 0) {
foundButNotConnected = steelseriesHeadsets.reduce((menuItems, device: UsbDevice) => {
menuItems.push({
label: device.realDevice().product,
submenu: [
{ label: `Product ID: ${device.productId}` },
{ label: `Bytes: Uknown` },
{ label: `Report: Uknown` },
{ label: `Path: ${device.path()}` },
],
});

return menuItems;
}, []);
}

if (foundHeadphones.length > 0) {
probeMenuItems = foundHeadphones.reduce((menuItems, result: ProbeResult) => {
menuItems.push({
label: result.device.realDevice().product,
submenu: [
{ label: `Product ID: ${result.device.productId}` },
{ label: `Bytes: ${result.matchedBytes}` },
{ label: `Report: ${result.matchedReport}` },
{ label: `Path: ${result.device.path()}` },
],
});

return menuItems;
}, []);
}

return new MenuItem({
label: 'Debug',
type: 'submenu',
submenu: [
{ label: 'Found but not connected', submenu: foundButNotConnected },
{ label: 'Found and possibly not confirgured', submenu: probeMenuItems },
],
});
}

export default debugMenu;
13 changes: 13 additions & 0 deletions src/menu_items/help.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MenuItem } from 'electron';

const helpMenuItem = () =>
new MenuItem({
label: 'Help',
type: 'normal',
click: async () => {
const { shell } = require('electron');
await shell.openExternal('https://github.com/richrace/arctis-monitor');
},
});

export default helpMenuItem;
12 changes: 12 additions & 0 deletions src/menu_items/quit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { app, MenuItem } from 'electron';

const quitMenuItem = () =>
new MenuItem({
label: 'Quit',
type: 'normal',
click: () => {
app.quit();
},
});

export default quitMenuItem;
92 changes: 18 additions & 74 deletions src/tray.ts
Original file line number Diff line number Diff line change
@@ -1,93 +1,36 @@
import { Tray, Menu, MenuItem } from 'electron';
import SimpleHeadphone from 'arctis-usb-finder/dist/interfaces/simple_headphone';

const { app, Tray, Menu, MenuItem } = require('electron');
const { getHeadphones, refreshHeadphones } = require('arctis-usb-finder');
import exportView from './headphone_view';
import debugMenu from './menu_items/debug';
import helpMenuItem from './menu_items/help';
import quitMenuItem from './menu_items/quit';
import loadHeadphones from './load_headphones';

let mainTray: any;

let cachedHeadphones: SimpleHeadphone[] = undefined;

function loadHeadphones(force: boolean = false): SimpleHeadphone[] {
if (force || cachedHeadphones === undefined) {
cachedHeadphones = getHeadphones();
console.log('forced', cachedHeadphones);
} else {
cachedHeadphones = refreshHeadphones(cachedHeadphones);
console.log('not forced', cachedHeadphones);
}

return cachedHeadphones;
}

const parseHeadphone = (headphone: SimpleHeadphone) => {
if (!headphone.isConnected) {
mainTray.setTitle('');
return { label: `${headphone.modelName} - Not connected`, type: 'normal' };
}

let percentage = headphone.batteryPercent > 100 ? 100 : headphone.batteryPercent;
percentage = percentage < 0 ? 0 : percentage;

let text = `${headphone.modelName} - ${percentage}%`;

// Set the Tool Tip and title so we don't have to click to see a percentage
mainTray.setToolTip(`${text}`);
mainTray.setTitle(` ${percentage}%`);

if (headphone.isCharging) {
text += ' 🔋 ';
}

if (headphone.isDischarging) {
text += ' 🪫 ';
}
const buildTrayMenu = (force: boolean = false, debug: boolean = false) => {
const headphones: SimpleHeadphone[] = loadHeadphones(force);
const menuItems = headphones.map((headphone) => exportView(mainTray, headphone));

if (headphone.isMuted) {
text += ' 🔇 ';
} else {
text += ' 🔊 ';
if (menuItems.length === 0) {
menuItems.push(new MenuItem({ label: 'No headphones found', type: 'normal' }));
}

return { label: text };
};

const quitMenuItem = () =>
new MenuItem({
label: 'Quit',
type: 'normal',
click: () => {
app.quit();
},
});
menuItems.push(new MenuItem({ label: '', type: 'separator' }));

const helpMenuItem = () =>
new MenuItem({
label: 'Help',
type: 'normal',
click: async () => {
const { shell } = require('electron');
await shell.openExternal('https://github.com/richrace/arctis-monitor');
},
});

const buildTrayMenu = (force: boolean = false) => {
const headphones: SimpleHeadphone[] = loadHeadphones(force);

let menuItems = headphones.map(parseHeadphone);

if (menuItems.length === 0) {
menuItems.push({ label: 'No headphones found', type: 'normal' });
if (debug) {
menuItems.push(debugMenu());
}

menuItems.push({ label: '', type: 'separator' });
menuItems.push(helpMenuItem());
menuItems.push(quitMenuItem());

const contextMenu = Menu.buildFromTemplate(menuItems);
mainTray.setContextMenu(contextMenu);
};

const buildTray = (path: any) => {
const createTray = (path: any) => {
const assetsDirectory = path.join(__dirname, '../assets');
mainTray = new Tray(path.join(assetsDirectory, 'headphones.png'));

Expand All @@ -98,7 +41,8 @@ const buildTray = (path: any) => {
mainTray.setContextMenu(contextMenu);

mainTray.on('click', (event: { altKey: boolean }) => {
buildTrayMenu(event.altKey);
const debug = event.altKey;
buildTrayMenu(debug, debug);
});

buildTrayMenu();
Expand All @@ -112,4 +56,4 @@ setInterval(buildTrayMenu, minute);
const thirtyMinutes = 10 * 60 * 1000;
setInterval(() => buildTrayMenu(true), thirtyMinutes);

module.exports = { createTray: buildTray };
export default createTray;

0 comments on commit 355fc11

Please sign in to comment.