Skip to content

Commit db15547

Browse files
TypeScript and update to hap-server 0.9.1
1 parent 1d43582 commit db15547

File tree

7 files changed

+658
-568
lines changed

7 files changed

+658
-568
lines changed

package-lock.json

+538-530
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,22 @@
2424
"node": ">=8.0.0 <12"
2525
},
2626
"dependencies": {
27-
"@hap-server/hap-server": "^0.7.0",
28-
"electron": "^5.0.4",
27+
"@hap-server/hap-server": "^0.9.1",
28+
"electron": "^6.0.12",
2929
"electron-window-state": "^5.0.3",
30-
"node-persist": "^3.0.4",
30+
"node-persist": "^3.0.5",
3131
"ws": "^6.2.1"
3232
},
3333
"devDependencies": {
3434
"babel-core": "^6.26.3",
3535
"babel-preset-env": "^1.7.0",
3636
"gulp": "^4.0.1",
3737
"gulp-babel": "^7.0.1",
38-
"pump": "^3.0.0"
38+
"pump": "^3.0.0",
39+
"typescript": "^3.6.4"
3940
},
4041
"scripts": {
41-
"build": "gulp build",
42+
"build": "tsc",
4243
"start": "electron dist/app",
4344
"interactive": "electron --interactive --require ./dist/app"
4445
},

src/app/index.js src/app/index.ts

+83-30
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import electron, {Tray, Menu, BrowserWindow, Notification, ipcMain, session} from 'electron';
1+
import {
2+
Tray, Menu, BrowserWindow, Notification, ipcMain, session, nativeImage, systemPreferences, app as electron_app,
3+
} from 'electron';
24
import path from 'path';
35
import fs from 'fs';
46
import url from 'url';
@@ -16,9 +18,21 @@ log.info('Starting');
1618
const persist_path = path.resolve(__dirname, '..', '..', 'data');
1719
const server_url = 'http://127.0.0.1:8082';
1820

19-
export class App {
21+
class App {
22+
static tray: Tray;
23+
static menu: Menu;
24+
static storage: typeof persist;
25+
static preferences_window?: BrowserWindow;
26+
27+
readonly client: Client;
28+
private _url: string;
29+
window?: BrowserWindow;
30+
31+
ready = false;
32+
2033
constructor() {
2134
this.client = new Client(server_url, WebSocket);
35+
this.client.loadAccessories(this);
2236

2337
this.url = server_url;
2438

@@ -39,6 +53,7 @@ export class App {
3953
}
4054
set url(base_url) {
4155
this._url = base_url;
56+
// @ts-ignore
4257
if (this.window) this.window.send('url', base_url);
4358

4459
const parsed = url.parse(base_url);
@@ -50,17 +65,20 @@ export class App {
5065
return this.client.url;
5166
}
5267
set websocket_url(url) {
68+
// @ts-ignore
5369
this.client.url = url;
5470
if (this.client.connected) this.client.disconnect().then(() => this.client.tryConnect());
5571
// if (this.window) this.window.send('reset-has-connected');
5672
}
5773

5874
async connected(connection) {
59-
log.info('Connected to %s', client.url, client);
75+
log.info('Connected to %s', this.client.url, this.client);
6076

77+
// @ts-ignore
6178
if (this.window) this.window.send('up');
6279

6380
connection.on('received-broadcast', data => {
81+
// @ts-ignore
6482
if (this.window) this.window.send('b', data);
6583
});
6684

@@ -70,7 +88,7 @@ export class App {
7088
this.constructor.menu.items[2].enabled = true;
7189

7290
this.constructor.tray.setContextMenu(this.constructor.menu);
73-
if (process.platform === 'darwin') electron.app.dock.setMenu(this.constructor.menu);
91+
if (process.platform === 'darwin') electron_app.dock.setMenu(this.constructor.menu);
7492

7593
const token = await this.constructor.storage.getItem('Token');
7694
if (this.ready && token) {
@@ -83,9 +101,11 @@ export class App {
83101
}
84102

85103
disconnected(event) {
86-
log.warn('Disconnected from %s', client.url, event);
104+
log.warn('Disconnected from %s', this.client.url, event);
87105

106+
// @ts-ignore
88107
if (this.window) this.window.send('down');
108+
// @ts-ignore
89109
if (this.constructor.preferences_window) this.constructor.preferences_window.send('authenticated-user', null);
90110

91111
if (event !== 1005) this.client.tryConnect();
@@ -94,7 +114,7 @@ export class App {
94114
this.constructor.menu.items[2].enabled = false;
95115

96116
this.constructor.tray.setContextMenu(this.constructor.menu);
97-
if (process.platform === 'darwin') electron.app.dock.setMenu(this.constructor.menu);
117+
if (process.platform === 'darwin') electron_app.dock.setMenu(this.constructor.menu);
98118
}
99119

100120
handleUpdateCharateristic(accessory_uuid, service_uuid, characteristic_uuid, details) {
@@ -118,6 +138,7 @@ export class App {
118138
title: this.name,
119139
subtitle: 'Characteristic updated',
120140
body: service.name + ' ' + (
141+
// @ts-ignore
121142
characteristic.type === characteristic.constructor.On ? characteristic.value ? 'on' : 'off' :
122143
''),
123144
});
@@ -139,9 +160,11 @@ export class App {
139160
Object.defineProperty(authenticated_user, 'asset_token', {value: response.asset_token});
140161
Object.assign(authenticated_user, response.data);
141162

163+
// @ts-ignore
142164
this.client.connection.authenticated_user = authenticated_user;
143165

144166
if (this.constructor.preferences_window) {
167+
// @ts-ignore
145168
this.constructor.preferences_window.send('authenticated-user', {
146169
id: authenticated_user.id,
147170
token: authenticated_user.token,
@@ -151,7 +174,7 @@ export class App {
151174
}
152175

153176
this.client.connection.getHomeSettings().then(d => this.client.home_settings = d);
154-
this.client.refreshAccessories();
177+
this.client.refreshLoaded();
155178

156179
return authenticated_user;
157180
}
@@ -166,12 +189,12 @@ export class App {
166189
} else if (data.type === 'get-accessories') {
167190
return event.sender.send('r', {
168191
messageid,
169-
response: data.id.map(uuid => this.client.accessories[uuid]._details),
192+
response: data.id.map(uuid => this.client.accessories[uuid].details),
170193
});
171194
} else if (data.type === 'get-accessories-data') {
172195
return event.sender.send('r', {
173196
messageid,
174-
response: data.id.map(uuid => this.client.accessories[uuid]._data),
197+
response: data.id.map(uuid => this.client.accessories[uuid].data),
175198
});
176199
} else if (data.type === 'get-home-settings') {
177200
return event.sender.send('r', {
@@ -191,9 +214,11 @@ export class App {
191214
Object.assign(authenticated_user, response.data);
192215

193216
log.info('AuthenticatedUser', authenticated_user);
217+
// @ts-ignore
194218
this.client.connection.authenticated_user = authenticated_user;
195219

196220
if (this.constructor.preferences_window) {
221+
// @ts-ignore
197222
this.constructor.preferences_window.send('authenticated-user', {
198223
id: authenticated_user.id,
199224
token: authenticated_user.token,
@@ -205,12 +230,12 @@ export class App {
205230
await this.constructor.storage.setItem('Token', authenticated_user.token);
206231

207232
this.client.connection.getHomeSettings().then(d => this.client.home_settings = d);
208-
this.client.refreshAccessories();
233+
this.client.refreshLoaded();
209234
} else if (data.type === 'set-accessories-data') {
210-
for (const [uuid, data] of data.id_data) {
235+
for (const [uuid, accessory_data] of data.id_data) {
211236
this.client.handleBroadcastMessage({
212237
type: 'update-accessory-data',
213-
uuid, data,
238+
uuid, data: accessory_data,
214239
});
215240
}
216241
} else if (data.type === 'set-home-settings') {
@@ -252,7 +277,9 @@ export class App {
252277
this.window.setMenuBarVisibility(false);
253278
this.window.setAutoHideMenuBar(true);
254279

280+
// @ts-ignore
255281
this.window.base_url = this.url;
282+
// @ts-ignore
256283
this.window.connected = this.client.connected;
257284

258285
window_state.manage(this.window);
@@ -262,7 +289,7 @@ export class App {
262289
this.window.once('ready-to-show', () => {
263290
this.window.show();
264291

265-
if (process.platform === 'darwin') electron.app.dock.show();
292+
if (process.platform === 'darwin') electron_app.dock.show();
266293
});
267294

268295
// Emitted when the window is closed
@@ -273,16 +300,16 @@ export class App {
273300
this.window = null;
274301
window_state.unmanage();
275302

276-
if (process.platform === 'darwin' && !BrowserWindow.getAllWindows().length) electron.app.dock.hide();
303+
if (process.platform === 'darwin' && !BrowserWindow.getAllWindows().length) electron_app.dock.hide();
277304
});
278305
}
279306

280-
static async ready(launch_info) {
307+
static async ready(launch_info?) {
281308
log.info('Launch info', launch_info);
282309

283310
require('./menu');
284311

285-
const icon = electron.nativeImage
312+
const icon = nativeImage
286313
.createFromPath(path.resolve(__dirname, '..', '..', 'assets', 'home-icon.png'))
287314
.resize({height: 22});
288315
icon.setTemplateImage(true);
@@ -298,7 +325,7 @@ export class App {
298325
]);
299326

300327
this.tray.setContextMenu(this.menu);
301-
if (process.platform === 'darwin') electron.app.dock.setMenu(this.menu);
328+
if (process.platform === 'darwin') electron_app.dock.setMenu(this.menu);
302329

303330
session.defaultSession.webRequest.onBeforeSendHeaders(this.onBeforeSendHeaders.bind(this));
304331

@@ -327,6 +354,7 @@ export class App {
327354
app.ready = true;
328355

329356
// If we're not authenticated open the main window so the user can authenticate
357+
// @ts-ignore
330358
if (!app.client.connection.authenticated_user) app.showWindow();
331359
}
332360

@@ -363,7 +391,7 @@ export class App {
363391
this.preferences_window.once('ready-to-show', () => {
364392
this.preferences_window.show();
365393

366-
if (process.platform === 'darwin') electron.app.dock.show();
394+
if (process.platform === 'darwin') electron_app.dock.show();
367395
});
368396

369397
// Emitted when the window is closed
@@ -374,14 +402,18 @@ export class App {
374402
this.preferences_window = null;
375403
window_state.unmanage();
376404

377-
if (process.platform === 'darwin' && !BrowserWindow.getAllWindows().length) electron.app.dock.hide();
405+
if (process.platform === 'darwin' && !BrowserWindow.getAllWindows().length) electron_app.dock.hide();
378406
});
379407
}
380408

381409
static onBeforeSendHeaders(details, callback) {
382-
if (!app.client.connection || !app.client.connection.authenticated_user) return callback({requestHeaders: details.requestHeaders});
410+
// @ts-ignore
411+
if (!app.client.connection || !app.client.connection.authenticated_user) {
412+
return callback({requestHeaders: details.requestHeaders});
413+
}
383414

384415
const requestHeaders = Object.assign({}, details.requestHeaders, {
416+
// @ts-ignore
385417
'Cookie': 'asset_token=' + app.client.connection.authenticated_user.asset_token,
386418
});
387419

@@ -393,10 +425,15 @@ export class App {
393425
}
394426

395427
static handleGetAuthenticatedUser(event) {
428+
// @ts-ignore
396429
event.sender.send('authenticated-user', app.client.connection && app.client.connection.authenticated_user ? {
430+
// @ts-ignore
397431
id: app.client.connection.authenticated_user.id,
432+
// @ts-ignore
398433
token: app.client.connection.authenticated_user.token,
434+
// @ts-ignore
399435
asset_token: app.client.connection.authenticated_user.asset_token,
436+
// @ts-ignore
400437
data: app.client.connection.authenticated_user,
401438
} : null);
402439
}
@@ -410,7 +447,13 @@ export class App {
410447
}
411448
}
412449

413-
electron.app.setAboutPanelOptions({
450+
interface App {
451+
constructor: typeof App;
452+
}
453+
454+
export {App};
455+
456+
electron_app.setAboutPanelOptions({
414457
applicationName: 'Home',
415458
applicationVersion: require('../../package').version,
416459
credits: 'https://gitlab.fancy.org.uk/hap-server/electron-app',
@@ -420,10 +463,17 @@ electron.app.setAboutPanelOptions({
420463

421464
export const app = new App();
422465

423-
electron.app.whenReady().then(() => App.ready());
424-
electron.app.on('activate', app.showWindow.bind(app));
466+
electron_app.whenReady().then(() => App.ready());
467+
electron_app.on('activate', app.showWindow.bind(app));
468+
469+
electron_app.on('browser-window-created', (event, window) => {
470+
// @ts-ignore
471+
window.base_url = app.url;
472+
// @ts-ignore
473+
window.connected = app.client.connected;
474+
});
425475

426-
electron.app.on('window-all-closed', () => {
476+
electron_app.on('window-all-closed', () => {
427477
// Don't quit as we want to stay connected to the server to show notifications
428478
});
429479

@@ -432,26 +482,29 @@ ipcMain.on('get-authenticated-user', App.handleGetAuthenticatedUser.bind(App));
432482
ipcMain.on('set-preferences', App.handleSetPreferences.bind(App));
433483

434484
if (process.platform === 'darwin') {
435-
electron.app.dock.hide();
485+
electron_app.dock.hide();
436486

437-
electron.systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => {
438-
electron.systemPreferences.setAppLevelAppearance(electron.systemPreferences.isDarkMode() ? 'dark' : 'light');
487+
systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => {
488+
systemPreferences.setAppLevelAppearance(systemPreferences.isDarkMode() ? 'dark' : 'light');
439489
});
440-
electron.systemPreferences.setAppLevelAppearance(electron.systemPreferences.isDarkMode() ? 'dark' : 'light');
490+
systemPreferences.setAppLevelAppearance(systemPreferences.isDarkMode() ? 'dark' : 'light');
441491
}
442492

443-
const interactive = !electron.app.isPackaged && process.argv.includes('--interactive');
493+
const interactive = !electron_app.isPackaged && process.argv.includes('--interactive');
444494

445495
if (interactive) {
446-
electron.app.on('quit', () => {
496+
electron_app.on('quit', () => {
447497
require('repl').repl.close();
448498
});
449499

450500
log.warn('Disabling logging for REPL');
451501
console.log = console.error = () => {};
452502

503+
// @ts-ignore
453504
global.App = App;
505+
// @ts-ignore
454506
global.app = app;
455507

508+
// @ts-ignore
456509
global.accessories = app.client.accessories;
457510
}

src/app/menu.js src/app/menu.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const template = [
4646
},
4747
],
4848
},
49-
];
49+
] as Electron.MenuItemConstructorOptions[];
5050

5151
const menu = Menu.buildFromTemplate(template);
5252
Menu.setApplicationMenu(menu);

0 commit comments

Comments
 (0)