Skip to content

Commit

Permalink
Convert main-process to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
martpie committed Aug 20, 2018
1 parent 6a12b26 commit 01e7abb
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 256 deletions.
9 changes: 0 additions & 9 deletions src/main/lib/modules-manager.js

This file was deleted.

7 changes: 7 additions & 0 deletions src/main/lib/modules-manager.ts
@@ -0,0 +1,7 @@
import Module from '../modules/module';

export const init = (...modules: Module[]) => {
modules.forEach((module) => {
module.init();
});
};
53 changes: 26 additions & 27 deletions src/main/main.js → src/main/main.ts
@@ -1,20 +1,17 @@
import * as path from 'path';
import * as electron from 'electron';

import IpcModule from './modules/ipc'; // Manages IPC events
import MenuModule from './modules/menu'; // Manage menu
import TrayModule from './modules/tray'; // Manages Tray
import ConfigModule from './modules/config'; // Handles config
import PowerModule from './modules/power-monitor'; // Handle power events
import ThumbarModule from './modules/thumbar'; // Handle Windows Thumbar
import DockMenuModule from './modules/dock-menu';
import GlobalShortcutsModule from './modules/global-shortcuts';

const path = require('path');
const os = require('os');
const electron = require('electron');

const IpcModule = require('./modules/ipc'); // Manages IPC events
const MenuModule = require('./modules/menu'); // Manage menu
const TrayModule = require('./modules/tray'); // Manages Tray
const ConfigModule = require('./modules/config'); // Handles config
const PowerModule = require('./modules/power-monitor'); // Handle power events
const ThumbarModule = require('./modules/thumbar'); // Handle Windows Thumbar
const DockMenuModule = require('./modules/dock-menu');
const GlobalShortcutsModule = require('./modules/global-shortcuts');

const ModulesManager = require('./lib/modules-manager');
const { checkBounds } = require('./utils');
import * as ModulesManager from './lib/modules-manager';
import { checkBounds } from './utils';

const { app, BrowserWindow } = electron;

Expand All @@ -23,7 +20,7 @@ const uiDistPath = path.join(appRoot, 'dist/ui');

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
let mainWindow = null;
let mainWindow: Electron.BrowserWindow | null = null;

// Make the app a single-instance app
const shouldQuit = app.makeSingleInstance(() => {
Expand Down Expand Up @@ -51,16 +48,16 @@ app.on('window-all-closed', () => {
app.on('ready', () => {
const configModule = new ConfigModule();
ModulesManager.init(
configModule,
configModule
);

const config = configModule.getConfig();
let { bounds } = config;

bounds = checkBounds(bounds);

// Browser Window options
const mainWindowOptions = {
// Create the browser window
mainWindow = new BrowserWindow({
title: 'Museeks',
x: bounds.x,
y: bounds.y,
Expand All @@ -72,15 +69,13 @@ app.on('ready', () => {
autoHideMenuBar: true,
titleBarStyle: 'hiddenInset', // MacOS polished window
show: false
};

// Create the browser window
mainWindow = new BrowserWindow(mainWindowOptions);
});

// ... and load the html page generated by Webpack
mainWindow.loadURL(`file://${uiDistPath}/index.html#/library`);

// Open dev tools if museeks is run in debug mode
// @ts-ignore I don't know why it triggers this error
if (process.argv.includes('--devtools')) mainWindow.openDevTools({ mode: 'detach' });

mainWindow.on('closed', () => {
Expand All @@ -89,13 +84,17 @@ app.on('ready', () => {
});

mainWindow.on('ready-to-show', () => {
mainWindow.show();
if (mainWindow) {
mainWindow.show();
}
});

// Click on the dock icon to show the app again on macOS
app.on('activate', () => {
mainWindow.show();
mainWindow.focus();
if (mainWindow) {
mainWindow.show();
mainWindow.focus();
}
});

// Prevent webContents from opening new windows (e.g ctrl-click on link)
Expand All @@ -110,6 +109,6 @@ app.on('ready', () => {
new TrayModule(mainWindow),
new ThumbarModule(mainWindow),
new DockMenuModule(mainWindow),
new GlobalShortcutsModule(mainWindow),
new GlobalShortcutsModule(mainWindow)
);
});
45 changes: 26 additions & 19 deletions src/main/modules/config.js → src/main/modules/config.ts
Expand Up @@ -2,19 +2,26 @@
* Essential module for creating/loading the app config
*/

const teeny = require('teeny-conf');
const electron = require('electron');
const path = require('path');
import * as electron from 'electron';
import * as teeny from 'teeny-conf';
import * as path from 'path';

const Module = require('./module');
import Module from './module';
import { Config, Repeat, SortBy, SortOrder } from '../../shared/types/interfaces';

const { app } = electron;


class ConfigModule extends Module {
load() {
protected workArea: Electron.Rectangle;
protected conf: typeof teeny;

constructor () {
super();

this.workArea = electron.screen.getPrimaryDisplay().workArea;
}

load () {
const defaultConfig = this.getDefaultConfig();
const pathUserData = app.getPath('userData');

Expand All @@ -24,7 +31,7 @@ class ConfigModule extends Module {
// Check if config update
let configChanged = false;

Object.keys(defaultConfig).forEach((key) => {
(Object.keys(defaultConfig) as (keyof Config)[]).forEach((key) => {
if (this.conf.get(key) === undefined) {
this.conf.set(key, defaultConfig[key]);
configChanged = true;
Expand All @@ -35,43 +42,43 @@ class ConfigModule extends Module {
if (configChanged) this.conf.saveSync();
}

getDefaultConfig() {
getDefaultConfig (): Config {
return {
theme: 'light',
audioVolume: 1,
audioPlaybackRate: 1,
audioMuted: false,
audioShuffle: false,
audioRepeat: 'none',
audioRepeat: Repeat.NONE,
librarySort: {
by: 'artist',
order: 'asc',
by: SortBy.ARTIST,
order: SortOrder.ASC
},
musicFolders: [],
// musicFolders: [],
sleepBlocker: false,
autoUpdateChecker: true,
minimizeToTray: true,
displayNotifications: true,
bounds: {
width: 1000,
height: 600,
x: parseInt(this.workArea.width / 2, 10),
y: parseInt(this.workArea.height / 2, 10),
},
x: this.workArea.width / 2,
y: this.workArea.height / 2
}
};
}

getConfig() {
getConfig () {
return this.conf.getAll();
}

get(key) {
get (key: keyof Config) {
return this.conf.get(key);
}

reload() {
reload () {
this.conf.loadOrCreateSync(this.getDefaultConfig());
}
}

module.exports = ConfigModule;
export default ConfigModule;
67 changes: 38 additions & 29 deletions src/main/modules/dock-menu.js → src/main/modules/dock-menu.ts
Expand Up @@ -2,104 +2,113 @@
* Module in charge of the dock menu on macOS
*/

const { Menu, app, ipcMain } = require('electron');

const ModuleWindow = require('./module-window');
import { Menu, app, ipcMain } from 'electron';

import ModuleWindow from './module-window';
import { PlayerStatus, TrackModel } from '../../shared/types/interfaces';

class DockMenuModule extends ModuleWindow {
constructor(window) {
protected menu: Electron.MenuItemConstructorOptions[];
protected songDetails: Electron.MenuItemConstructorOptions[];
protected playToggle: Electron.MenuItemConstructorOptions[];
protected pauseToggle: Electron.MenuItemConstructorOptions[];

constructor (window: Electron.BrowserWindow) {
super(window);
this.platforms = ['darwin'];

this.menu = [];
this.songDetails = [];
this.playToggle = [];
this.pauseToggle = [];
}

load() {
load () {
this.songDetails = [
{
label: 'Not playing',
enabled: false,
enabled: false
},
{
type: 'separator',
},
type: 'separator'
}
];

this.playToggle = [
{
label: 'Play',
click: () => {
this.window.webContents.send('playback:play');
},
},
}
}
];

this.pauseToggle = [
{
label: 'Pause',
click: () => {
this.window.webContents.send('playback:pause');
},
},
}
}
];

this.menu = [
{
label: 'Previous',
click: () => {
this.window.webContents.send('playback:previous');
},
}
},
{
label: 'Next',
click: () => {
this.window.webContents.send('playback:next');
},
},
}
}
];

// Load events listener for player actions
ipcMain.on('playback:play', () => {
this.setDockMenu('play');
this.setDockMenu(PlayerStatus.PLAY);
});

ipcMain.on('playback:pause', () => {
this.setDockMenu('pause');
this.setDockMenu(PlayerStatus.PAUSE);
});

ipcMain.on('playback:trackChange', (event, track) => {
ipcMain.on('playback:trackChange', (_e: Event, track: TrackModel) => {
this.updateTrayMetadata(track);
this.setDockMenu('play');
this.setDockMenu(PlayerStatus.PLAY);
});

this.setDockMenu('pause');
this.setDockMenu(PlayerStatus.PAUSE);
}

setDockMenu(state) {
setDockMenu (state: PlayerStatus) {
const playPauseItem = state === 'play' ? this.pauseToggle : this.playToggle;
const menuTemplate = [...this.songDetails, ...playPauseItem, ...this.menu];
app.dock.setMenu(Menu.buildFromTemplate(menuTemplate));
}


updateTrayMetadata(metadata) {
updateTrayMetadata (metadata: TrackModel) {
this.songDetails = [
{
label: `${metadata.title}`,
enabled: false,
enabled: false
},
{
label: `by ${metadata.artist}`,
enabled: false,
enabled: false
},
{
label: `on ${metadata.album}`,
enabled: false,
enabled: false
},
{
type: 'separator',
},
type: 'separator'
}
];
}
}

module.exports = DockMenuModule;
export default DockMenuModule;
Expand Up @@ -2,12 +2,11 @@
* Module in charge of registering global shortcuts
*/

const { globalShortcut } = require('electron');
const ModuleWindow = require('./module-window');

import { globalShortcut } from 'electron';
import ModuleWindow from './module-window';

class GlobalShortcutsModule extends ModuleWindow {
load() {
load () {
globalShortcut.register('MediaPlayPause', () => {
this.window.webContents.send('playback:playpause');
});
Expand All @@ -22,4 +21,4 @@ class GlobalShortcutsModule extends ModuleWindow {
}
}

module.exports = GlobalShortcutsModule;
export default GlobalShortcutsModule;

0 comments on commit 01e7abb

Please sign in to comment.