From ec8fea8d7b5f28a91f25bb57e1aa0d6ca1c07978 Mon Sep 17 00:00:00 2001 From: Drew Ewing Date: Tue, 6 Sep 2022 21:59:27 -0700 Subject: [PATCH 1/5] feat(delegates): config fixes & custom delegates included (wip) --- .env.example | 3 ++- config.ts | 23 +++++++++++------------ libraries/Iridium/IridiumManager.ts | 2 +- libraries/Iridium/webrtc/WebRTCManager.ts | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.env.example b/.env.example index 05e9139bc7..376f724fb9 100644 --- a/.env.example +++ b/.env.example @@ -2,5 +2,6 @@ # in case you want to run Cypress locally ENVIRONMENT=dev -NUXT_ENV_IRIDIUM_SYNC_NODES= '/ip4/138.197.229.159/tcp/4003/ws,/ip4/138.197.229.159/tcp/4002' +# NUXT_ENV_IRIDIUM_SYNC_NODES= '/ip4/138.197.229.159/tcp/4003/ws,/ip4/138.197.229.159/tcp/4002' +NUXT_ENV_IRIDIUM_SYNC_NODES= '/ip4/127.0.0.1/tcp/4003/ws,/ip4/127.0.0.1/tcp/4005/ws' # '/dns4/localhost/tcp/443/wss/p2p/12D3KooWRgdhiJam4naWGYtgLXtc17ty89MMPvig41p9BhKG7FRW' diff --git a/config.ts b/config.ts index 32d0ca8b4e..7b080b0d79 100644 --- a/config.ts +++ b/config.ts @@ -1,25 +1,24 @@ // eslint-disable-next-line import/named import { Commitment } from '@solana/web3.js' +import type { IridiumConfig } from '@satellite-im/iridium' -const syncNodes = process.env.NUXT_ENV_IRIDIUM_SYNC_NODES?.split(',') || [ +const nodes = process.env.NUXT_ENV_IRIDIUM_SYNC_NODES?.split(',') || [ '/ip4/localhost/tcp/443/wss/p2p/12D3KooWRgdhiJam4naWGYtgLXtc17ty89MMPvig41p9BhKG7FRW', ] -console.log('debug: | syncNodes', syncNodes) - +const gateways = process.env.NUXT_ENV_IRIDIUM_GATEWAYS?.split(',') || [ + 'https://satellite.infura-ipfs.io', +] export const Config = { debug: true, iridium: { - syncNodes, + nodes, + gateways, ipfs: { config: { - Addresses: { - Swarm: syncNodes, - Delegate: syncNodes, - }, - Bootstrap: syncNodes, + Bootstrap: nodes, }, }, - }, + } as Partial, ipfs: { gateway: 'https://satellite.infura-ipfs.io/ipfs/', }, @@ -206,13 +205,13 @@ export const Config = { }, seedPhraseCharsCount: 12, pip: { - /* Grid config, image splitting the screen in `rows x columns` + /* Grid config, image splitting the screen in `rows x columns` _____ _____ |_____|_____| |_____|_____| |_____|_____| |_____|_____| - + Depending on the center of the Pip, it will land on a specific slot */ rows: [0, 1, 2, 3] as const, diff --git a/libraries/Iridium/IridiumManager.ts b/libraries/Iridium/IridiumManager.ts index e066d57af0..b68bf099e9 100644 --- a/libraries/Iridium/IridiumManager.ts +++ b/libraries/Iridium/IridiumManager.ts @@ -74,8 +74,8 @@ export class IridiumManager extends Emitter { async initFromEntropy(entropy: Uint8Array) { logger.info('iridium/manager', 'initFromEntropy()') this.connector = await createIridiumIPFS(entropy, { + ...Config.iridium, logger, - nodes: Config.iridium.syncNodes, }) logger.info('iridium/manager', 'connector initialized', { diff --git a/libraries/Iridium/webrtc/WebRTCManager.ts b/libraries/Iridium/webrtc/WebRTCManager.ts index f61fe9f632..7afcf996ca 100644 --- a/libraries/Iridium/webrtc/WebRTCManager.ts +++ b/libraries/Iridium/webrtc/WebRTCManager.ts @@ -17,7 +17,7 @@ import { Conversation } from '~/libraries/Iridium/chat/types' const $Sounds = new SoundManager() -const announceFrequency = 15000 +const announceFrequency = 60000 const initialState: WebRTCState = { incomingCall: null, From a4380c4e763a8afb12e9d22688adb10e1729b17e Mon Sep 17 00:00:00 2001 From: Drew Ewing Date: Wed, 7 Sep 2022 13:21:17 -0700 Subject: [PATCH 2/5] feat(performance): misc. perf fixes & call time --- components/views/media/heading/Heading.html | 6 +- components/views/media/heading/Heading.vue | 16 +++--- libraries/Iridium/IridiumManager.ts | 64 +++++++++++++-------- libraries/Iridium/users/UsersManager.ts | 8 ++- libraries/Iridium/webrtc/WebRTCManager.ts | 4 +- libraries/Iridium/webrtc/types.ts | 1 + locales/en-US.js | 2 +- 7 files changed, 62 insertions(+), 39 deletions(-) diff --git a/components/views/media/heading/Heading.html b/components/views/media/heading/Heading.html index c5b38698da..edff2eb40c 100644 --- a/components/views/media/heading/Heading.html +++ b/components/views/media/heading/Heading.html @@ -1,5 +1,5 @@ -
- - {{$t('ui.live', { time: formatDuration(callTime / 1000) })}} +
+ + {{$t('ui.live', { time: callTimeString })}}
diff --git a/components/views/media/heading/Heading.vue b/components/views/media/heading/Heading.vue index b73ebab032..f98a2edbe1 100644 --- a/components/views/media/heading/Heading.vue +++ b/components/views/media/heading/Heading.vue @@ -13,16 +13,16 @@ export default Vue.extend({ }, data() { return { - callTime: 0, - formatDuration, + webrtc: iridium.webRTC.state, + callTimeString: '', } }, - mounted() { - setInterval(this.updateCallTime, 1000) - }, - methods: { - updateCallTime() { - this.callTime = iridium.webRTC.callTime + watch: { + webrtc: { + handler() { + this.callTimeString = this.$dayjs(this.webrtc.callStartedAt).toNow(true) + }, + deep: true, }, }, }) diff --git a/libraries/Iridium/IridiumManager.ts b/libraries/Iridium/IridiumManager.ts index b68bf099e9..d578371078 100644 --- a/libraries/Iridium/IridiumManager.ts +++ b/libraries/Iridium/IridiumManager.ts @@ -116,29 +116,27 @@ export class IridiumManager extends Emitter { logger.info('iridium/manager', 'initializing profile') await this.profile.init() - await new Promise((resolve) => - setTimeout(() => this.sendSyncInit().then(() => resolve(true)), 3000), - ) + await this.connector?.waitForSyncNode(5000) + await this.sendSyncInit() } async onProfileChange() { logger.debug('iridium/manager', 'profile changed', { primaryNodeID: this.connector?.p2p.primaryNodeID, - p2pReady: this.connector?.p2p.ready, - did: this.profile.state?.did, + nodeReady: this.connector?.p2p.nodeReady, }) - if (!this.connector?.p2p.ready) { + if (!this.connector?.p2p.primaryNodeID || !this.connector?.p2p.nodeReady) { return } - if (this.profile.state?.did) { - await this.sendSyncInit() - } + await this.sendSyncInit() } async onP2pReady() { if ( !this.profile.state?.did || !this.connector?.p2p.primaryNodeID || + !this.connector?.p2p.hasNode || + !this.connector?.p2p.nodeReady || !this.connector.p2p.ready ) { logger.debug( @@ -147,6 +145,8 @@ export class IridiumManager extends Emitter { { primaryNodeID: this.connector?.p2p.primaryNodeID, p2pReady: this.connector?.p2p.ready, + nodeReady: this.connector?.p2p.nodeReady, + hasNode: this.connector?.p2p.hasNode, did: this.profile.state?.did, }, ) @@ -155,20 +155,38 @@ export class IridiumManager extends Emitter { if (this.ready) return logger.info('iridium/manager', 'initializing users') await this.users.init() - logger.info('iridium/manager', 'initializing groups') - await this.groups.init() - logger.info('iridium/manager', 'initializing files') - await this.files.init() - logger.info('iridium/manager', 'initializing webRTC') - await this.webRTC.init() - logger.info('iridium/manager', 'initializing settings') - await this.settings.init() - logger.info('iridium/manager', 'notification settings') - await this.notifications.init() - logger.info('iridium/friends', 'initializing friends') - await this.friends.init() - logger.info('iridium/manager', 'initializing chat') - await this.chat.init() + await Promise.all( + [ + async () => { + logger.info('iridium/manager', 'initializing groups') + await this.groups.init() + }, + async () => { + logger.info('iridium/manager', 'initializing files') + await this.files.init() + }, + async () => { + logger.info('iridium/manager', 'initializing webRTC') + await this.webRTC.init() + }, + async () => { + logger.info('iridium/manager', 'initializing settings') + await this.settings.init() + }, + async () => { + logger.info('iridium/manager', 'notification settings') + await this.notifications.init() + }, + async () => { + logger.info('iridium/friends', 'initializing friends') + await this.friends.init() + }, + async () => { + logger.info('iridium/manager', 'initializing chat') + await this.chat.init() + }, + ].map((f) => f()), + ) logger.info('iridium/manager', 'ready') logger.info( diff --git a/libraries/Iridium/users/UsersManager.ts b/libraries/Iridium/users/UsersManager.ts index 3fff8d0f18..4c534d1b93 100644 --- a/libraries/Iridium/users/UsersManager.ts +++ b/libraries/Iridium/users/UsersManager.ts @@ -65,6 +65,7 @@ export default class UsersManager extends Emitter { await iridium.connector.subscribe('/users/announce', { handler: this.onUsersAnnounce.bind(this), sync: true, + decode: false, }) logger.log(this.loggerTag, 'listening for user activity', this.state) @@ -248,7 +249,10 @@ export default class UsersManager extends Emitter { return new Promise((resolve) => { const id = v4() - if (!iridium.connector?.p2p.primaryNodeID || !iridium.ready) { + if ( + !iridium.connector?.p2p.primaryNodeID || + !iridium.connector?.p2p.nodeReady + ) { logger.warn('iridium/usermanager', 'no primary node, cannot search', { primaryNodeID: iridium?.connector?.p2p.primaryNodeID, p2pReady: iridium?.connector?.p2p.ready, @@ -260,7 +264,7 @@ export default class UsersManager extends Emitter { const timeout = setTimeout(() => { logger.warn(this.loggerTag, 'peer search timeout', { query }) resolve([]) - }, 30000) + }, 5000) this.once(`searchResults/${id}`, (results: User[]) => { logger.debug(this.loggerTag, 'search results received', results) diff --git a/libraries/Iridium/webrtc/WebRTCManager.ts b/libraries/Iridium/webrtc/WebRTCManager.ts index 7afcf996ca..747b966842 100644 --- a/libraries/Iridium/webrtc/WebRTCManager.ts +++ b/libraries/Iridium/webrtc/WebRTCManager.ts @@ -23,6 +23,7 @@ const initialState: WebRTCState = { incomingCall: null, activeCall: null, streamMuted: {}, + callTime: 0, callStartedAt: 0, streamConstraints: { audio: true, @@ -47,7 +48,6 @@ type WebRTCTypingMessage = { export default class WebRTCManager extends Emitter { public state: WebRTCState private loggerTag = 'iridium/webRTC' - public callTime: number = 0 public timers: { [key: string]: any } = {} constructor() { @@ -84,7 +84,7 @@ export default class WebRTCManager extends Emitter { setInterval(() => { if (this.state.activeCall) { - this.callTime = Date.now() - this.state.callStartedAt + this.state.callTime = Date.now() - this.state.callStartedAt } }, 1000) } diff --git a/libraries/Iridium/webrtc/types.ts b/libraries/Iridium/webrtc/types.ts index 48072287ac..d13176266a 100644 --- a/libraries/Iridium/webrtc/types.ts +++ b/libraries/Iridium/webrtc/types.ts @@ -28,6 +28,7 @@ export interface WebRTCState { streamMuted: StreamMutedState activeCall: WebRTCActiveCall | null incomingCall: WebRTCIncomingCall | null + callTime: number callStartedAt: number streamConstraints: WebRTCStreamConstraints } diff --git a/locales/en-US.js b/locales/en-US.js index 1998aebb0b..6901ed111b 100644 --- a/locales/en-US.js +++ b/locales/en-US.js @@ -35,7 +35,7 @@ export default { fullscreen: 'Fullscreen', exit_fullscreen: 'Exit fullscreen', more: 'More', - live: 'Live {time}', + live: 'Live for {time}', edited: 'edited', online: 'All users are offline | {name} is online | {name} are online', offline: '{name} is not connected', From 7a4c250f69c4fef8d631b62410ae64cf38c496fe Mon Sep 17 00:00:00 2001 From: Drew Ewing Date: Wed, 7 Sep 2022 16:10:02 -0700 Subject: [PATCH 3/5] feat(sync): send sync init after registration --- store/accounts/actions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/store/accounts/actions.ts b/store/accounts/actions.ts index 8cd98bc50d..930c4450ee 100644 --- a/store/accounts/actions.ts +++ b/store/accounts/actions.ts @@ -299,6 +299,7 @@ export default { commit('setRegistrationStatus', RegistrationStatus.REGISTERED) commit('setActiveAccount', iridium.id) commit('setUserDetails', profile) + await iridium.sendSyncInit() return dispatch('startup', walletAccount) }, From eb8a21c2b7761979534e8c634ce8e69cdca43e31 Mon Sep 17 00:00:00 2001 From: Drew Ewing Date: Wed, 7 Sep 2022 16:24:46 -0700 Subject: [PATCH 4/5] feat(sync): don't send init without did --- libraries/Iridium/IridiumManager.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/Iridium/IridiumManager.ts b/libraries/Iridium/IridiumManager.ts index 7223840f79..05ba886fcb 100644 --- a/libraries/Iridium/IridiumManager.ts +++ b/libraries/Iridium/IridiumManager.ts @@ -212,6 +212,9 @@ export class IridiumManager extends Emitter { return } const profile = this.profile.state + if (!profile?.did) { + return + } logger.info('iridium/manager', 'sending sync init', { profile }) const payload = { type: 'sync/init', From c987dc2d1c1fbfab3d85fe42bf0cfc0dbbb0cd0f Mon Sep 17 00:00:00 2001 From: Drew Ewing Date: Wed, 7 Sep 2022 16:49:10 -0700 Subject: [PATCH 5/5] feat(sync): debounce sync init --- libraries/Iridium/IridiumManager.ts | 52 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/libraries/Iridium/IridiumManager.ts b/libraries/Iridium/IridiumManager.ts index 05ba886fcb..f489b2c8b0 100644 --- a/libraries/Iridium/IridiumManager.ts +++ b/libraries/Iridium/IridiumManager.ts @@ -26,6 +26,7 @@ export class IridiumManager extends Emitter { webRTC: WebRTCManager settings: SettingsManager users: UsersManager + syncTimeout?: NodeJS.Timeout constructor() { super() @@ -203,29 +204,36 @@ export class IridiumManager extends Emitter { } async sendSyncInit() { - const connector = this.connector - if (!connector?.p2p.primaryNodeID) { - logger.warn('iridium/manager', 'no primary node, cannot send sync init', { - primaryNodeID: connector?.p2p.primaryNodeID, - ready: connector?.p2p.ready, - }) - return - } - const profile = this.profile.state - if (!profile?.did) { - return - } - logger.info('iridium/manager', 'sending sync init', { profile }) - const payload = { - type: 'sync/init', - at: Date.now(), - name: profile?.name || this.id, - avatar: profile?.photoHash || '', - status: profile?.status || '', - photoHash: profile?.photoHash || '', - } + clearTimeout(this.syncTimeout) + this.syncTimeout = setTimeout(() => { + const connector = this.connector + if (!connector?.p2p.primaryNodeID) { + logger.warn( + 'iridium/manager', + 'no primary node, cannot send sync init', + { + primaryNodeID: connector?.p2p.primaryNodeID, + ready: connector?.p2p.ready, + }, + ) + return + } + const profile = this.profile.state + if (!profile?.did) { + return + } + logger.info('iridium/manager', 'sending sync init', { profile }) + const payload = { + type: 'sync/init', + at: Date.now(), + name: profile?.name || this.id, + avatar: profile?.photoHash || '', + status: profile?.status || '', + photoHash: profile?.photoHash || '', + } - await connector.send(connector.p2p.primaryNodeID, payload) + connector.send(connector.p2p.primaryNodeID, payload) + }, 3000) } }