Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 64 additions & 46 deletions shared/constants/init/index.desktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,19 @@ const onInstallCachedDokan = async () => {
}
}

const _platformUnsubs: Array<() => void> = __DEV__
? ((globalThis as any).__hmr_platformUnsubs ??= [])
: []

let _oneTimeInitDone: boolean = __DEV__
? ((globalThis as any).__hmr_oneTimeInitDone ?? false)
: false

export const initPlatformListener = () => {
// HMR cleanup: unsubscribe old store subscriptions before re-subscribing
for (const unsub of _platformUnsubs) unsub()
_platformUnsubs.length = 0

useConfigState.setState(s => {
s.dispatch.defer.dumpLogsNative = dumpLogs
s.dispatch.defer.showMainNative = wrapErrors(() => showMainWindow?.())
Expand All @@ -266,12 +278,12 @@ export const initPlatformListener = () => {
})
})

useConfigState.subscribe((s, old) => {
_platformUnsubs.push(useConfigState.subscribe((s, old) => {
if (s.appFocused === old.appFocused) return
useFSState.getState().dispatch.onChangedFocus(s.appFocused)
})
}))

useConfigState.subscribe((s, old) => {
_platformUnsubs.push(useConfigState.subscribe((s, old) => {
if (s.loggedIn !== old.loggedIn) {
s.dispatch.osNetworkStatusChanged(navigator.onLine, 'notavailable', true)
}
Expand Down Expand Up @@ -310,32 +322,60 @@ export const initPlatformListener = () => {
}
ignorePromise(f())
}
})
}))

const handleWindowFocusEvents = () => {
const handle = (appFocused: boolean) => {
if (skipAppFocusActions) {
console.log('Skipping app focus actions!')
} else {
useConfigState.getState().dispatch.changedFocus(appFocused)
// One-time setup: window event listeners and input monitor (skip on HMR to avoid duplicates)
if (!_oneTimeInitDone) {
_oneTimeInitDone = true
if (__DEV__) (globalThis as any).__hmr_oneTimeInitDone = true

const handleWindowFocusEvents = () => {
const handle = (appFocused: boolean) => {
if (skipAppFocusActions) {
console.log('Skipping app focus actions!')
} else {
useConfigState.getState().dispatch.changedFocus(appFocused)
}
}
window.addEventListener('focus', () => handle(true))
window.addEventListener('blur', () => handle(false))
}
window.addEventListener('focus', () => handle(true))
window.addEventListener('blur', () => handle(false))
}
handleWindowFocusEvents()
handleWindowFocusEvents()

const setupReachabilityWatcher = () => {
window.addEventListener('online', () =>
useConfigState.getState().dispatch.osNetworkStatusChanged(true, 'notavailable')
)
window.addEventListener('offline', () =>
useConfigState.getState().dispatch.osNetworkStatusChanged(false, 'notavailable')
)
}
setupReachabilityWatcher()

const setupReachabilityWatcher = () => {
window.addEventListener('online', () =>
useConfigState.getState().dispatch.osNetworkStatusChanged(true, 'notavailable')
)
window.addEventListener('offline', () =>
useConfigState.getState().dispatch.osNetworkStatusChanged(false, 'notavailable')
)
if (isLinux) {
useConfigState.getState().dispatch.initUseNativeFrame()
}
useConfigState.getState().dispatch.initNotifySound()
useConfigState.getState().dispatch.initForceSmallNav()
useConfigState.getState().dispatch.initOpenAtLogin()
useConfigState.getState().dispatch.initAppUpdateLoop()

const initializeInputMonitor = () => {
const inputMonitor = new InputMonitor()
inputMonitor.notifyActive = (userActive: boolean) => {
if (skipAppFocusActions) {
console.log('Skipping app focus actions!')
} else {
useConfigState.getState().dispatch.setActive(userActive)
// let node thread save file
activeChanged?.(Date.now(), userActive)
}
}
}
initializeInputMonitor()
}
setupReachabilityWatcher()

useDaemonState.subscribe((s, old) => {
_platformUnsubs.push(useDaemonState.subscribe((s, old) => {
if (s.handshakeVersion !== old.handshakeVersion) {
if (!isWindows) return

Expand Down Expand Up @@ -368,15 +408,7 @@ export const initPlatformListener = () => {
tab: undefined,
})
}
})

if (isLinux) {
useConfigState.getState().dispatch.initUseNativeFrame()
}
useConfigState.getState().dispatch.initNotifySound()
useConfigState.getState().dispatch.initForceSmallNav()
useConfigState.getState().dispatch.initOpenAtLogin()
useConfigState.getState().dispatch.initAppUpdateLoop()
}))

useProfileState.setState(s => {
s.dispatch.editAvatar = () => {
Expand All @@ -386,20 +418,6 @@ export const initPlatformListener = () => {
}
})

const initializeInputMonitor = () => {
const inputMonitor = new InputMonitor()
inputMonitor.notifyActive = (userActive: boolean) => {
if (skipAppFocusActions) {
console.log('Skipping app focus actions!')
} else {
useConfigState.getState().dispatch.setActive(userActive)
// let node thread save file
activeChanged?.(Date.now(), userActive)
}
}
}
initializeInputMonitor()

useDaemonState.setState(s => {
s.dispatch.onRestartHandshakeNative = () => {
const {handshakeFailedReason} = useDaemonState.getState()
Expand Down
35 changes: 24 additions & 11 deletions shared/constants/init/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,15 @@ import {useRouterState} from '@/stores/router2'
import * as Util from '@/constants/router2'
import {setConvoDefer} from '@/stores/convostate'

let _emitStartupOnLoadDaemonConnectedOnce = false
let _devicesLoaded = false
let _gitLoaded = false
let _emitStartupOnLoadDaemonConnectedOnce: boolean = __DEV__
? ((globalThis as any).__hmr_startupOnce ?? false)
: false
let _devicesLoaded: boolean = __DEV__ ? ((globalThis as any).__hmr_devicesLoaded ?? false) : false
let _gitLoaded: boolean = __DEV__ ? ((globalThis as any).__hmr_gitLoaded ?? false) : false

const _sharedUnsubs: Array<() => void> = __DEV__
? ((globalThis as any).__hmr_sharedUnsubs ??= [])
: []

export const onEngineConnected = () => {
{
Expand Down Expand Up @@ -397,6 +403,10 @@ export const initSettingsCallbacks = () => {
}

export const initSharedSubscriptions = () => {
// HMR cleanup: unsubscribe old store subscriptions before re-subscribing
for (const unsub of _sharedUnsubs) unsub()
_sharedUnsubs.length = 0

setConvoDefer({
chatBlockButtonsMapHas: teamID =>
storeRegistry.getState('chat').blockButtonsMap.has(teamID),
Expand All @@ -423,7 +433,7 @@ export const initSharedSubscriptions = () => {
usersGetBio: username =>
storeRegistry.getState('users').dispatch.getBio(username),
})
useConfigState.subscribe((s, old) => {
_sharedUnsubs.push(useConfigState.subscribe((s, old) => {
if (s.loadOnStartPhase !== old.loadOnStartPhase) {
if (s.loadOnStartPhase === 'startupOrReloginButNotInARush') {
const getFollowerInfo = () => {
Expand Down Expand Up @@ -546,9 +556,9 @@ export const initSharedSubscriptions = () => {
const cs = storeRegistry.getConvoState(getSelectedConversation())
cs.dispatch.markThreadAsRead()
}
})
}))

useDaemonState.subscribe((s, old) => {
_sharedUnsubs.push(useDaemonState.subscribe((s, old) => {
if (s.handshakeVersion !== old.handshakeVersion) {
useDarkModeState.getState().dispatch.loadDarkPrefs()
storeRegistry.getState('chat').dispatch.loadStaticConfig()
Expand Down Expand Up @@ -587,13 +597,14 @@ export const initSharedSubscriptions = () => {
if (s.handshakeState === 'done') {
if (!_emitStartupOnLoadDaemonConnectedOnce) {
_emitStartupOnLoadDaemonConnectedOnce = true
if (__DEV__) (globalThis as any).__hmr_startupOnce = true
useConfigState.getState().dispatch.loadOnStart('connectedToDaemonForFirstTime')
}
}
}
})
}))

useProvisionState.subscribe((s, old) => {
_sharedUnsubs.push(useProvisionState.subscribe((s, old) => {
if (s.startProvisionTrigger !== old.startProvisionTrigger) {
useConfigState.getState().dispatch.setLoginError()
useConfigState.getState().dispatch.resetRevokedSelf()
Expand All @@ -605,9 +616,9 @@ export const initSharedSubscriptions = () => {
}
ignorePromise(f())
}
})
}))

useRouterState.subscribe((s, old) => {
_sharedUnsubs.push(useRouterState.subscribe((s, old) => {
const next = s.navState as Util.NavState
const prev = old.navState as Util.NavState
if (prev === next) return
Expand Down Expand Up @@ -684,7 +695,7 @@ export const initSharedSubscriptions = () => {
}

storeRegistry.getState('chat').dispatch.onRouteChanged(prev, next)
})
}))

initAutoResetCallbacks()
initChat2Callbacks()
Expand Down Expand Up @@ -721,13 +732,15 @@ export const _onEngineIncoming = (action: EngineGen.Actions) => {
const hasValue = (newDevices?.length ?? 0) + (revokedDevices?.length ?? 0) > 0
if (_devicesLoaded || hasValue) {
_devicesLoaded = true
if (__DEV__) (globalThis as any).__hmr_devicesLoaded = true
const {useDevicesState} = require('@/stores/devices') as typeof UseDevicesStateType
useDevicesState.getState().dispatch.onEngineIncomingImpl(action)
}

const badges = new Set(badgeState.newGitRepoGlobalUniqueIDs)
if (_gitLoaded || badges.size) {
_gitLoaded = true
if (__DEV__) (globalThis as any).__hmr_gitLoaded = true
const {useGitState} = require('@/stores/git') as typeof UseGitStateType
useGitState.getState().dispatch.onEngineIncomingImpl(action)
}
Expand Down
5 changes: 3 additions & 2 deletions shared/desktop/renderer/main2.desktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,9 @@ const setupHMR = () => {

const load = () => {
if (global.DEBUGLoaded) {
// only load once
console.log('Bail on load() on HMR')
// HMR detected — reinit subscriptions on new store instances
console.log('HMR: reinitializing store subscriptions')
initPlatformListener()
return
}
global.DEBUGLoaded = true
Expand Down
9 changes: 7 additions & 2 deletions shared/stores/convostate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -431,10 +431,13 @@ const stubDefer: ConvoState['dispatch']['defer'] = {
},
}

let convoDeferImpl: ConvoState['dispatch']['defer'] | undefined
let convoDeferImpl: ConvoState['dispatch']['defer'] | undefined = __DEV__
? (globalThis as any).__hmr_convoDeferImpl
: undefined

export const setConvoDefer = (impl: ConvoState['dispatch']['defer']) => {
convoDeferImpl = impl
if (__DEV__) (globalThis as any).__hmr_convoDeferImpl = impl
for (const store of chatStores.values()) {
const s = store.getState()
store.setState({
Expand Down Expand Up @@ -3313,7 +3316,9 @@ const createSlice = (): Z.ImmerStateCreator<ConvoState> => (set, get) => {
}

type MadeStore = UseBoundStore<StoreApi<ConvoState>>
export const chatStores = new Map<T.Chat.ConversationIDKey, MadeStore>()
export const chatStores: Map<T.Chat.ConversationIDKey, MadeStore> = __DEV__
? ((globalThis as any).__hmr_chatStores ??= new Map())
: new Map()

export const clearChatStores = () => {
chatStores.clear()
Expand Down
4 changes: 3 additions & 1 deletion shared/stores/team-building.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,9 @@ const createSlice: Z.ImmerStateCreator<State> = (set, get) => {
}

type MadeStore = UseBoundStore<StoreApi<State>>
export const TBstores = new Map<T.TB.AllowedNamespace, MadeStore>()
export const TBstores: Map<T.TB.AllowedNamespace, MadeStore> = __DEV__
? ((globalThis as any).__hmr_TBstores ??= new Map())
: new Map()

registerDebugClear(() => {
TBstores.clear()
Expand Down