Skip to content

Commit b31abda

Browse files
Heartbeat (#35)
* fix: fixed error during logon when the user_data contain connection=false that resolve in an infinite loop of restart app; * restored heathbeat API call after login; * fix add connection check Co-authored-by: Edoardo Spadoni <[email protected]>
1 parent 93f5464 commit b31abda

File tree

17 files changed

+287
-219
lines changed

17 files changed

+287
-219
lines changed

package-lock.json

Lines changed: 15 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"@fortawesome/react-fontawesome": "^0.2.0",
4646
"@headlessui/react": "^1.7.18",
4747
"@hookform/resolvers": "^3.3.4",
48-
"@nethesis/phone-island": "^0.8.18",
48+
"@nethesis/phone-island": "^0.8.20",
4949
"@tailwindcss/forms": "^0.5.7",
5050
"@types/lodash": "^4.14.202",
5151
"@types/node": "^18.19.9",

src/main/classes/controllers/AccountController.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import fs, { access } from 'fs'
33
import { Account, AuthAppData, ConfigFile } from '@shared/types'
44
import { log } from '@shared/utils/logger'
55
import { safeStorage } from 'electron'
6-
import { store, useStoreState } from '@/lib/mainStore'
6+
import { store } from '@/lib/mainStore'
77
import { useNethVoiceAPI } from '@shared/useNethVoiceAPI'
88
import { useLogin } from '@shared/useLogin'
99
import { NetworkController } from './NetworkController'
@@ -128,16 +128,18 @@ export class AccountController {
128128

129129

130130
updateTheme(theme: any) {
131-
const account = store.store.account
132-
store.set('theme', theme)
133-
if (account) {
134-
account.theme = theme
131+
if (store.store) {
132+
const account = store.store.account
133+
store.set('theme', theme)
134+
if (account) {
135+
account.theme = theme
135136

136-
store.set('account', account)
137-
const auth = store.store.auth
137+
store.set('account', account)
138+
const auth = store.store.auth
138139

139-
auth!.availableAccounts[getAccountUID(account)] = account
140-
store.set('auth', auth)
140+
auth!.availableAccounts[getAccountUID(account)] = account
141+
store.set('auth', auth)
142+
}
141143
}
142144
}
143145

src/main/lib/ipcEvents.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { NethLinkController } from '@/classes/controllers/NethLinkController'
1111
import { AppController } from '@/classes/controllers/AppController'
1212
import moment from 'moment'
1313
import { store } from './mainStore'
14-
import { debouncer, getPageFromQuery, isDev } from '@shared/utils/utils'
14+
import { debouncer, getAccountUID, getPageFromQuery } from '@shared/utils/utils'
1515
import { NetworkController } from '@/classes/controllers/NetworkController'
1616
import { useLogin } from '@shared/useLogin'
1717
import { PhoneIslandWindow } from '@/classes/windows'
@@ -155,8 +155,13 @@ export function registerIpcEvents() {
155155

156156

157157
ipcMain.on(IPC_EVENTS.UPDATE_CONNECTION_STATE, (event, isOnline) => {
158-
log('CONNECTION STATE', isOnline, event.sender.getTitle())
159-
store.set('connection', isOnline)
158+
if (store.store) {
159+
log('CONNECTION STATE', isOnline)
160+
store.set('connection', isOnline)
161+
if (!store.store.account) {
162+
store.saveToDisk()
163+
}
164+
}
160165
});
161166

162167
ipcMain.on(IPC_EVENTS.REQUEST_SHARED_STATE, (event) => {
@@ -189,6 +194,15 @@ export function registerIpcEvents() {
189194
ipcMain.on(IPC_EVENTS.LOGIN_WINDOW_RESIZE, (event, h) => {
190195
LoginController.instance.resize(h)
191196
})
197+
ipcMain.on(IPC_EVENTS.DELETE_ACCOUNT, (event, account: Account) => {
198+
log('DELETE ACCOUNT', account)
199+
const accountUID = getAccountUID(account)
200+
const newStore = Object.assign({}, store.store)
201+
delete newStore.auth!.availableAccounts[accountUID]
202+
store.set('auth', newStore.auth, true)
203+
store.updateStore(newStore, 'delete account')
204+
store.saveToDisk(true)
205+
})
192206
ipcMain.on(IPC_EVENTS.HIDE_LOGIN_WINDOW, () => {
193207
LoginController.instance.hide()
194208
})

src/main/lib/mainStore.ts

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LocalStorageData } from '@shared/types';
1+
import { Account, LocalStorageData } from '@shared/types';
22
import { app, ipcMain } from 'electron';
33
import path from 'path';
44
import fs from 'fs';
@@ -7,12 +7,27 @@ import { log } from '@shared/utils/logger';
77
import { difference, differenceBy, differenceWith } from 'lodash';
88

99
const USER_DATA_PATH = path.join(app.getPath("userData"), 'user_data.json');
10+
const AVAILABLE_USER_DATA_PATH = path.join(app.getPath("userData"), 'available_user_data.json');
1011

1112
class Store<T> {
1213

14+
1315
constructor() {
14-
if (!fs.existsSync(USER_DATA_PATH)) {
15-
fs.writeFileSync(USER_DATA_PATH, JSON.stringify({}))
16+
if (!fs.existsSync(USER_DATA_PATH) || !fs.existsSync(AVAILABLE_USER_DATA_PATH)) {
17+
if (!fs.existsSync(AVAILABLE_USER_DATA_PATH)) {
18+
if (!fs.existsSync(USER_DATA_PATH)) {
19+
fs.writeFileSync(AVAILABLE_USER_DATA_PATH, JSON.stringify({}))
20+
} else {
21+
const data = fs.readFileSync(USER_DATA_PATH, 'utf-8');
22+
const retrivedStore: LocalStorageData = JSON.parse(data);
23+
if (retrivedStore.auth?.availableAccounts) {
24+
fs.writeFileSync(AVAILABLE_USER_DATA_PATH, JSON.stringify(retrivedStore.auth!.availableAccounts))
25+
} else {
26+
fs.writeFileSync(AVAILABLE_USER_DATA_PATH, JSON.stringify({}))
27+
}
28+
}
29+
}
30+
!fs.existsSync(USER_DATA_PATH) && fs.writeFileSync(USER_DATA_PATH, JSON.stringify({}))
1631
} else {
1732
this.store = this.getFromDisk()
1833
}
@@ -24,31 +39,47 @@ class Store<T> {
2439
return this.store[selector]
2540
}
2641

27-
set(selector: keyof T, value: any) {
42+
set(selector: keyof T, value: any, force: boolean = false) {
2843
const o = Object.assign({}, this.store)
2944
o[selector] = value
3045
const diff = difference(Object.values(o), Object.values(this.store as any))
31-
if (diff.length > 0) {
46+
log({ diff })
47+
if (diff.length > 0 || force) {
3248
this.store = o
3349
ipcMain.emit(IPC_EVENTS.UPDATE_SHARED_STATE, undefined, this.store, 'main', selector)
3450
}
3551
}
3652

3753
updateStore(newState: T, from: string) {
38-
const diff = difference(Object.values(newState as any), Object.values(this.store as any))
39-
if (diff.length > 0) {
54+
const diff = difference(Object.values(newState as any || {}), Object.values(this.store as any || {}))
55+
if (diff.length > 0 || this.store === undefined) {
4056
this.store = Object.assign({}, newState)
4157
}
4258
}
4359

44-
saveToDisk() {
60+
saveToDisk(forceSave: boolean = false) {
61+
const availableUserData = (this.store as LocalStorageData).auth?.availableAccounts
4562
fs.writeFileSync(USER_DATA_PATH, JSON.stringify(this.store));
63+
if (Object.keys(availableUserData || {}).length > 0 || forceSave) {
64+
fs.writeFileSync(AVAILABLE_USER_DATA_PATH, JSON.stringify(availableUserData));
65+
}
66+
}
67+
68+
getAvailableFromDisk(): { [accountUID: string]: Account; } {
69+
if (fs.existsSync(AVAILABLE_USER_DATA_PATH)) {
70+
const availableUserData = fs.readFileSync(AVAILABLE_USER_DATA_PATH, 'utf-8');
71+
return JSON.parse(availableUserData)
72+
}
73+
return {}
4674
}
4775

4876
getFromDisk() {
4977
try {
5078
const data = fs.readFileSync(USER_DATA_PATH, 'utf-8');
51-
return JSON.parse(data);
79+
const availableUserData = fs.readFileSync(AVAILABLE_USER_DATA_PATH, 'utf-8');
80+
const retrivedStore = JSON.parse(data);
81+
(retrivedStore as LocalStorageData).auth!.availableAccounts = JSON.parse(availableUserData)
82+
return retrivedStore
5283
} catch (error) {
5384
log('Error retrieving user data', error);
5485
// you may want to propagate the error, up to you
@@ -58,21 +89,6 @@ class Store<T> {
5889
}
5990

6091
export const store: Store<LocalStorageData> = new Store<LocalStorageData>()
61-
export function useStoreState<T>(selector: keyof LocalStorageData): [T | undefined, (arg0: T | ((ex: T) => T | undefined) | undefined) => void] {
62-
63-
const setter = (arg0: (T | undefined) | ((ex: T) => T | undefined)) => {
64-
let v: T | undefined = arg0 as (T | undefined)
65-
if (typeof arg0 === 'function') {
66-
v = (arg0 as (ex: T | undefined) => T | undefined)(store.store[selector] as T | undefined)
67-
}
68-
store.set(selector, v)
69-
}
70-
71-
return [
72-
store.get(selector) as T | undefined,
73-
setter
74-
]
75-
}
7692

7793

7894

0 commit comments

Comments
 (0)