mobx#reaction TypeScript Examples
The following examples show how to use
mobx#reaction.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: arrows.ts From hubble-ui with Apache License 2.0 | 6 votes |
constructor(frame: StoreFrame, placement: ServiceMapPlacementStrategy) {
super();
makeObservable(this);
this.interactions = frame.interactions;
this.services = frame.services;
this.placement = placement;
reaction(
() => this.arrowsMap,
() => {
this.rebuildArrowsMap();
},
{ delay: 10 },
);
}
Example #2
Source File: Service.ts From hive with MIT License | 6 votes |
constructor(store: Store, modelUuid: string) {
this.store = store;
this.modelUuid = modelUuid;
reaction(
() => this.store.viewModels.commonView.size,
size => {
const { widgets } = this.store.viewModels.dashboardView.currentPage;
const widget = widgets.find(x => x.uuid === this.modelUuid);
if (!widget) return;
widget.noViewOpenner = size === ScreenSize.big;
},
{
fireImmediately: true,
}
);
}
Example #3
Source File: DagContainer.ts From clarity with Apache License 2.0 | 6 votes |
constructor(
private errors: ErrorContainer,
private casperService: CasperServiceByJsonRPC,
private eventService: EventService
) {
this.toggleableSubscriber = new ToggleableSubscriber(
this.casperService,
e => this.subscriberHandler(e),
() => this.isLatestDag,
() => this.refreshBlockDag()
);
// react to the change of maxRank, depth, page and count, so that outer components only need to set DAG's props
// DAG manage the refresh by itself.
reaction(
() => {
return [this.maxRank, this.depth, this.page, this.count];
},
() => {
this.refreshBlockDagAndSetupSubscriber();
}
);
}
Example #4
Source File: Service.ts From hive with MIT License | 6 votes |
constructor(store: Store, modelUuid: string) {
this.store = store;
this.modelUuid = modelUuid;
reaction(
() => this.store.viewModels.commonView.size,
size => {
const { widgets } = this.store.viewModels.dashboardView.currentPage;
const widget = widgets.find(x => x.uuid === this.modelUuid);
if (!widget) return;
widget.noViewOpenner = size === ScreenSize.big;
},
{
fireImmediately: true,
}
);
}
Example #5
Source File: placement.ts From hubble-ui with Apache License 2.0 | 6 votes |
constructor(frame: StoreFrame) {
super();
makeObservable(this);
this.controls = frame.controls;
this.interactions = frame.interactions;
this.services = frame.services;
this._httpEndpointCoords = new Map();
reaction(
() => this.cardsPlacement,
() => this.releasePlacement(),
);
}
Example #6
Source File: extension.ts From gitdoc with MIT License | 6 votes |
export async function activate(context: vscode.ExtensionContext) {
const git = await getGitApi();
if (!git) {
return;
}
// Initialize the store based on the
// user/workspace configuration.
store.enabled = config.enabled;
registerCommands(context);
// Enable/disable the auto-commit watcher as the user
// opens/closes Git repos, modifies their settings
// and/or manually enables it via the command palette.
context.subscriptions.push(git.onDidOpenRepository(() => checkEnabled(git)));
context.subscriptions.push(git.onDidCloseRepository(() => checkEnabled(git)));
reaction(
() => [store.enabled],
() => checkEnabled(git)
);
context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration((e) => {
if (e.affectsConfiguration("gitdoc.enabled")) {
checkEnabled(git);
}
})
);
}
Example #7
Source File: store.ts From mysterium-vpn-desktop with MIT License | 6 votes |
setupReactions(): void {
when(
() => this.startupStatus == StartupStatus.UpdateNotAvailable,
async () => {
await this.start()
},
)
reaction(
() => this.status,
async (status) => {
if (status == DaemonStatusType.Down) {
log.info("Connection to Mysterium Node lost (auto-start in 5s)")
setTimeout(async () => {
if (this.status == DaemonStatusType.Down) {
await this.start()
} else {
log.info("Connection to Mysterium Node restored")
}
}, 5_000)
}
},
)
reaction(
() => this.status,
async (status) => {
if (status == DaemonStatusType.Up) {
this.eventSource = sseConnect()
}
},
)
this.root.navigation.showLoading()
this.update()
}
Example #8
Source File: KubeResourceChart.tsx From lens-resource-map-extension with MIT License | 6 votes |
async componentDidMount() {
this.setState(this.state);
this.registerStores();
await this.loadData();
this.displayChart();
const fg = this.chartRef.current;
//fg?.zoom(1.2, 1000);
fg?.d3Force('link').strength(2).distance(() => 60)
fg?.d3Force('charge', d33d.forceManyBody().strength(-60).distanceMax(250));
fg?.d3Force('collide', d3.forceCollide(40));
fg?.d3Force("center", d3.forceCenter());
const reactionOpts = {
equals: comparer.structural,
}
const { object } = this.props
const api = Renderer.K8sApi.apiManager.getApiByKind(object.kind, object.apiVersion);
const store = Renderer.K8sApi.apiManager.getStore(api);
this.disposers.push(reaction(() => this.props.object, (value, prev, _reaction) => { value.getId() !== prev.getId() ? this.displayChart() : this.refreshChart() }));
this.disposers.push(reaction(() => this.podsStore.items.toJSON(), (values, previousValue, _reaction) => { this.refreshItems(values, previousValue) }, reactionOpts));
this.disposers.push(reaction(() => store.items.toJSON(), (values, previousValue, _reaction) => { this.refreshItems(values, previousValue) }, reactionOpts));
}
Example #9
Source File: editor.tsx From nota with MIT License | 6 votes |
Viewer = observer(() => {
let viewerState = useContext(ViewerStateContext)!;
let state = useContext(StateContext)!;
let ref = useRef<HTMLDivElement>(null);
useEffect(() => {
let el = ref.current;
if (!el) {
return;
}
let lastScroll = 0;
el.addEventListener("scroll", _ => {
let scroll = el!.scrollTop;
let t = state.translation;
if (isOk(t) && scroll > 0) {
lastScroll = scroll;
}
});
reaction(
() => [state.translation],
() => {
if (el!.scrollTop == 0) {
el!.scrollTo(0, lastScroll);
}
}
);
}, [ref]);
return (
<div className="viewer" ref={ref}>
<Inner selected={viewerState.selected} />
</div>
);
})
Example #10
Source File: AppStore.ts From casl-examples with MIT License | 6 votes |
constructor(
private _http: Http
) {
reaction(() => this.token, (token) => {
if (token) {
this._http.defaults.headers.Authorization = token;
} else {
delete this._http.defaults.headers.Authorization;
}
});
reaction(() => this.rules, (rules) => this.ability.update(rules));
}
Example #11
Source File: demo-mode-panel.tsx From ya-webadb with MIT License | 6 votes |
constructor() {
makeAutoObservable(this);
reaction(
() => GlobalState.device,
async (device) => {
if (device) {
runInAction(() => this.demoMode = new DemoMode(device));
const allowed = await this.demoMode!.getAllowed();
runInAction(() => this.allowed = allowed);
if (allowed) {
const enabled = await this.demoMode!.getEnabled();
runInAction(() => this.enabled = enabled);
}
} else {
this.demoMode = undefined;
this.allowed = false;
this.enabled = false;
this.features.clear();
}
},
{ fireImmediately: true }
);
// Apply all features when enable
autorun(() => {
if (this.enabled) {
for (const group of FEATURES) {
for (const feature of group) {
feature.onChange(this.features.get(feature.key) ?? feature.initial);
}
}
}
});
}
Example #12
Source File: SettingsNotificationsViewModel.ts From companion-kit with MIT License | 6 votes |
init() {
this.updateEnabledState();
logger.log('init this.originalIsEnabled =', this.originalIsEnabled, 'this.isEnabled =', this.isEnabled);
this._unsubscribe = reaction(() => this.originalIsEnabled, enabled => {
logger.log('originalIsEnabled CHANGED:', enabled, ', this.isEnabled =', this.isEnabled);
if (this._toggleInProgress) {
return;
}
this.updateEnabledState();
});
}
Example #13
Source File: Instance.tsx From jmix-frontend with Apache License 2.0 | 6 votes |
constructor(public readonly entityName: string,
viewName: string = PredefinedView.MINIMAL,
stringIdName: string | null = null) {
this.viewName = viewName;
this.stringIdName = stringIdName;
makeObservable(this, {
item: observable,
status: observable,
lastError: observable,
viewName: observable,
stringIdName: observable,
load: action,
setItem: action,
setItemToFormFields: action,
update: action,
commit: action
});
reaction(
() => this.status,
action(status => this.lastError = status !== "ERROR" ? null : this.lastError)
)
}
Example #14
Source File: MultiselectViewModel.ts From companion-kit with MIT License | 6 votes |
constructor(items: T[], accessor: (item: T) => StringOrNumber, defaults: StringOrNumber[], validation?: ValidationConfig<T[]>) {
super(validation);
if (!items?.length) {
throw new Error('MultiSelect: items must be not empty');
}
this._items = items;
this._selected = items.filter(i => defaults.includes(i.value));
reaction(() => items, items2 => {
this._values = items2.map(accessor);
}, { fireImmediately: true });
}
Example #15
Source File: Collection.tsx From jmix-frontend with Apache License 2.0 | 6 votes |
constructor(public readonly entityName: string,
public readonly trackChanges = false,
viewName: string = PredefinedView.MINIMAL,
sort: string | null = null) {
this.view = viewName;
this.sort = sort;
makeObservable(this, {
items: observable,
status: observable,
lastError: observable,
view: observable,
sort: observable,
filter: observable,
limit: observable,
offset: observable,
count: observable,
skipCount: observable,
stringIdName: observable,
readOnlyItems: computed,
properties: computed
});
if (this.trackChanges) {
reaction(
() => [this.items, this.items.length],
() => {
this.changedItems.push(this.items)
}
)
}
reaction(() => this.status,
status => this.lastError = status !== "ERROR" ? null : this.lastError)
}
Example #16
Source File: SelectViewModel.ts From companion-kit with MIT License | 6 votes |
constructor(items: T[], accessor: (item: T) => string, initialIndex: number = 0, validation?: ValidationConfig<T>) {
super(validation);
this._items = items;
this._index = initialIndex;
this._accessor = accessor;
reaction(() => items, items2 => {
this._values = items2.map(accessor);
}, { fireImmediately: true });
}
Example #17
Source File: Router.tsx From jmix-frontend with Apache License 2.0 | 6 votes |
constructor() {
makeObservable(this);
this.setCurrentRoute();
window.addEventListener('popstate', this.setCurrentRoute);
window.addEventListener('hashchange', this.setCurrentRoute);
reaction(
() => {
return JSON.stringify(this.currentLocation);
},
() => {
eventEmitter.emit('navigate');
},
);
}
Example #18
Source File: Auth.ts From companion-kit with MIT License | 6 votes |
constructor() {
super();
this.initGoogle();
reaction(
() => AppQueryService.Instance.currentUrl,
() => this.updateLocationUrl(AppQueryService.Instance.currentUrl, AppQueryService.Instance.query),
{ fireImmediately: true, delay: 100 },
);
}
Example #19
Source File: ToggleableSubscriber.ts From clarity with Apache License 2.0 | 6 votes |
/**
* Construct a toggleable subscriber which will subscribe to CasperService.subscribeEvents.
* @param casperService
* @param eventHandler: a handler function for each received event
* @param additionalEnable: subscriber will only enable when both additionalEnable and subscribeToggleStore are true
* @param forceRefresh: a force refresh when toggle button switch from OFF to ON, so that it is deal with the latest state
*/
constructor(
private casperService: CasperServiceByJsonRPC,
private eventHandler: (event: Event) => void,
private additionalEnable: () => boolean,
private forceRefresh: () => void
) {
// so that change of subscribeToggleStore can trigger `setUpSubscriber`
reaction(
() => this.subscribeToggleStore.isPressed && this.additionalEnable(),
() => {
this.setUpSubscriber();
},
{
fireImmediately: false,
delay: 100
}
);
}
Example #20
Source File: base.tsx From companion-kit with MIT License | 6 votes |
componentDidMount() {
this.start();
if (this.enableGlobalProgressTracking) {
this.disposer.add(reaction(() => this.globalLoading, p => {
this.logger.log('Global Progress =', p);
if (p) {
Keyboard.dismiss();
this.allowInputAutoFocus = false;
this.hideModal();
this.savePersonaState('globalProgress', PersonaStates.Listen, PersonaViewPresets.Default);
} else {
this.restorePersonaState('globalProgress');
}
}, { fireImmediately: true }));
}
}
Example #21
Source File: MainStore.ts From jmix-frontend with Apache License 2.0 | 5 votes |
constructor(
private apolloClient: ApolloClient<unknown>,
private jmixREST: JmixRestConnection,
options?: MainStoreOptions
) {
this._appName = options?.appName ?? '';
this.storage = options?.storage ?? window.localStorage;
this.clientId = options?.clientId ?? 'client';
this.secret = options?.secret ?? 'secret';
this.obtainTokenEndpoint = options?.obtainTokenEndpoint ?? '/oauth/token';
this.revokeTokenEndpoint = options?.revokeTokenEndpoint ?? '/oauth/revoke';
this.locale = this.storage.getItem(this.localeStorageKey)
?? options?.locale
?? 'en';
this.graphqlEndpoint = options?.graphqlEndpoint ?? '/graphql';
if (options?.contentDisplayMode != null) {
this.contentDisplayMode = options.contentDisplayMode;
}
this.jmixREST.onLocaleChange(this.handleLocaleChange);
this.security = new Security(this.apolloClient);
makeObservable<MainStore, "handleLocaleChange">(this, {
initialized: observable,
authenticated: observable,
usingAnonymously: observable,
userName: observable,
locale: observable,
messages: observable,
enumMessages: observable,
contentDisplayMode: observable,
initialize: action,
loadMessages: action,
loginRequired: computed,
login: action,
logout: action,
handleLocaleChange: action
});
autorun(() => {
if (this.initialized && (this.authenticated || this.usingAnonymously)) {
this.security.loadPermissions();
this.loadMessages();
}
})
// Save locale to storage whenever it is changed
autorun(() => {
if (this.locale != null) {
this.storage.setItem(this.localeStorageKey, this.locale);
// TODO remove once REST is fully replaced by GraphQL.
this.jmixREST.locale = this.locale;
} else {
this.storage.removeItem(this.localeStorageKey);
}
});
reaction(() => this.locale, (locale) => {
this.localeChangeListeners.forEach((onLocaleChanged) => onLocaleChanged(locale));
});
}
Example #22
Source File: Channel.tsx From revite with GNU Affero General Public License v3.0 | 5 votes |
TextChannel = observer(({ channel }: { channel: ChannelI }) => {
const layout = useApplicationState().layout;
// Store unread location.
const [lastId, setLastId] = useState<string | undefined>(undefined);
useEffect(
() =>
internalSubscribe("NewMessages", "hide", () =>
setLastId(undefined),
),
[],
);
useEffect(
() => internalSubscribe("NewMessages", "mark", setLastId as any),
[],
);
// Mark channel as read.
useEffect(() => {
setLastId(
(channel.unread
? channel.client.unreads?.getUnread(channel._id)?.last_id
: undefined) ?? undefined,
);
const checkUnread = () =>
channel.unread &&
channel.client.unreads!.markRead(
channel._id,
channel.last_message_id!,
true,
);
checkUnread();
return reaction(
() => channel.last_message_id,
() => checkUnread(),
);
}, [channel]);
return (
<AgeGate
type="channel"
channel={channel}
gated={
!!(
(channel.channel_type === "TextChannel" ||
channel.channel_type === "Group") &&
channel.nsfw
)
}>
<ChannelHeader channel={channel} />
<ChannelMain>
<ErrorBoundary section="renderer">
<ChannelContent>
<VoiceHeader id={channel._id} />
<NewMessages channel={channel} last_id={lastId} />
<MessageArea channel={channel} last_id={lastId} />
<TypingIndicator channel={channel} />
<JumpToBottom channel={channel} />
<MessageBox channel={channel} />
</ChannelContent>
</ErrorBoundary>
{!isTouchscreenDevice &&
layout.getSectionState(SIDEBAR_MEMBERS, true) && (
<RightSidebar />
)}
</ChannelMain>
</AgeGate>
);
})
Example #23
Source File: remote-state.tsx From nota with MIT License | 5 votes |
constructor() {
let host = window.location.host;
this.ws = new WebSocket(`ws://${host}`);
this.ws.onerror = evt => {
console.error(evt);
};
this.ws.onopen = async () => {
let needsSync = false;
reaction(
() => [this.contents],
() => {
needsSync = true;
}
);
let sync = () => {
if (needsSync) {
needsSync = false;
let sync: SyncText = {
type: "SyncText",
contents: this.contents,
};
this.ws.send(JSON.stringify(sync));
}
};
// TODO: make auto-compile configurable
document.addEventListener("keydown", (evt: KeyboardEvent) => {
if ((evt.metaKey || evt.ctrlKey) && evt.key == "s") {
evt.stopPropagation();
evt.preventDefault();
sync();
}
});
// setInterval(sync, 1000);
};
this.ws.onmessage = action(event => {
let msg: Message = JSON.parse(event.data);
if (msg.type == "InitialContent") {
this.contents = msg.contents;
this.translation = msg.translation;
this.ready = true;
} else if (msg.type == "NewOutput") {
this.translation = msg.translation;
}
});
makeAutoObservable(this);
}
Example #24
Source File: Router.tsx From jmix-frontend with Apache License 2.0 | 5 votes |
Link = observer(
(props: ILinkProps) => {
const {
to,
exact = false,
dontIgnoreHash = false,
grabActive = null,
activeClass = null,
children = null,
className = null,
htmlAttrs = {},
...restProps
} = props;
const [state] = useState(() => observable({
active: false,
}));
useEffect(
() => reaction(
() => {
const { currentRegExp, currentLocation } = currentRoute;
return [to, exact, currentLocation, currentRegExp];
},
() => {
calcActive();
},
),
[],
);
const handleClick = useCallback((e) => {
e.preventDefault();
redirect(to);
}, []);
const calcActive = useCallback(() => {
const { currentRegExp, currentLocation } = currentRoute;
let active = false;
if (exact) {
if (dontIgnoreHash && !currentRoute.hashMode) {
active = to === currentLocation.fullPath + currentLocation.location.hash;
} else {
active = to === currentLocation.fullPath;
}
} else if (currentRegExp && currentRegExp.exec(to)) {
active = true;
}
if (active !== state.active) {
state.active = active;
if (grabActive) grabActive(active);
}
}, []);
useState(() => calcActive());
const classNames = [];
if (className) classNames.push(className);
if (activeClass && state.active) classNames.push(activeClass);
return (
<a {...restProps} {...htmlAttrs} className={classNames.join(' ')} href={to} data-active={state.active} onClick={handleClick}>
{children}
</a>
);
},
)
Example #25
Source File: KubeForceChart.tsx From lens-resource-map-extension with MIT License | 5 votes |
async componentDidMount() {
this.setState(this.state)
this.kubeObjectStores = [
this.podsStore,
this.deploymentStore,
this.statefulsetStore,
this.daemonsetStore,
this.serviceStore,
this.ingressStore,
this.pvcStore,
this.configMapStore,
this.secretStore,
]
await this.loadData();
this.displayChart();
const fg = this.chartRef.current;
fg.zoom(1.3, 1000);
fg?.d3Force('link').strength(1.3).distance(() => 60)
fg?.d3Force('charge', d33d.forceManyBody().strength(-60).distanceMax(250));
fg?.d3Force('collide', d3.forceCollide(40));
fg?.d3Force("center", d3.forceCenter());
const reactionOpts = {
equals: comparer.structural,
}
disposeOnUnmount(this, [
reaction(() => this.namespaceStore.selectedNamespaces, this.namespaceChanged, reactionOpts),
reaction(() => this.podsStore.items.toJSON(), () => { this.refreshItems(this.podsStore) }, reactionOpts),
reaction(() => this.daemonsetStore.items.toJSON(), () => { this.refreshItems(this.daemonsetStore) }, reactionOpts),
reaction(() => this.statefulsetStore.items.toJSON(), () => { this.refreshItems(this.statefulsetStore) }, reactionOpts),
reaction(() => this.deploymentStore.items.toJSON(), () => { this.refreshItems(this.deploymentStore) }, reactionOpts),
reaction(() => this.serviceStore.items.toJSON(), () => { this.refreshItems(this.serviceStore) }, reactionOpts),
reaction(() => this.secretStore.items.toJSON(), () => { this.refreshItems(this.secretStore) }, reactionOpts),
reaction(() => this.pvcStore.items.toJSON(), () => { this.refreshItems(this.pvcStore) }, reactionOpts),
reaction(() => this.ingressStore.items.toJSON(), () => { this.refreshItems(this.ingressStore) }, reactionOpts),
reaction(() => this.configMapStore.items.toJSON(), () => { this.refreshItems(this.configMapStore) }, reactionOpts)
])
}
Example #26
Source File: Service.ts From hive with MIT License | 5 votes |
constructor(store: Store, modelUuid: string) {
this.store = store;
this.modelUuid = modelUuid;
reaction(
() => this.store.viewModels.commonView.size,
size => {
const { widgets } = this.store.viewModels.dashboardView.currentPage;
const widget = widgets.find(x => x.uuid === this.modelUuid);
if (!widget) return;
widget.noViewOpenner = size === ScreenSize.big;
},
{
fireImmediately: true,
}
);
reaction(
() => {
return this.store.viewModels.conditionaireView.data.map(x => ({
id: x.id,
loading: x.loading,
}));
},
data => {
const { widgets } = this.store.viewModels.dashboardView.currentPage;
const widget = widgets.find(x => x.uuid === this.modelUuid);
if (!widget) return;
if (data) {
const meta = data.find(x => x.id === Number(widget.id.replace('c', '')));
if (meta) {
widget.loading = meta.loading;
}
}
}
);
}
Example #27
Source File: useHotkey.ts From jmix-frontend with Apache License 2.0 | 5 votes |
useScreenHotkey = (
hotkeyConfig: HotkeyConfig,
memoizedCallback: KeyHandler,
) => {
const {addHotkeyConfig, removeHotkeyConfigs} = useHotkeyStore();
const multiScreen = useMultiScreen();
const screens = useScreens();
const isScreen = multiScreen != null && screens != null;
const [currentTab, setCurrentTab] = useState(tabs.currentTab);
const parentScreenIsSelected = (
isScreen
&& currentTab?.title === multiScreen.title
&& screens?.currentScreen?.title === multiScreen.title
);
const childScreenIsSelected = (
isScreen
&& currentTab?.title === multiScreen.parent?.title
&& screens?.currentScreen?.title === multiScreen.title
);
useEffect(() => {
if (!isScreen) {
console.error('useScreenHotkey hook should be used inside the screen-api');
}
}, [isScreen])
useEffect(() => {
if (parentScreenIsSelected || childScreenIsSelected) {
hotkeys(hotkeyConfig.hotkey, memoizedCallback);
addHotkeyConfig(hotkeyConfig);
}
return () => {
if (parentScreenIsSelected || childScreenIsSelected) {
hotkeys.unbind(hotkeyConfig.hotkey, memoizedCallback);
removeHotkeyConfigs(hotkeyConfig);
}
};
}, [
hotkeyConfig,
childScreenIsSelected,
parentScreenIsSelected,
addHotkeyConfig,
removeHotkeyConfigs,
memoizedCallback,
]);
useEffect(() => {
const dispose = reaction(
() => tabs.currentTab,
setCurrentTab,
);
return dispose;
}, []);
}
Example #28
Source File: UserController.ts From companion-kit with MIT License | 5 votes |
constructor(protected readonly auth: IAuthController) {
this.disposer.add(
reaction(() => auth.authUser, authUser => this.init(authUser)),
'AUTH',
);
}
Example #29
Source File: store.ts From mysterium-vpn-desktop with MIT License | 5 votes |
setupReactions(): void {
eventBus.on(SSEEventType.AppStateChange, (state: AppState) => {
if (state.consumer?.connection) {
this.setStatus(state.consumer.connection.status)
this.setStatistics(state.consumer.connection.statistics)
}
if (state.consumer?.connection?.proposal) {
this.setProposal(newUIProposal(state.consumer.connection.proposal))
} else {
this.setProposal(undefined)
}
})
reaction(
() => this.root.daemon.status,
async (status) => {
if (status == DaemonStatusType.Up) {
await this.resolveOriginalLocation()
}
},
)
reaction(
() => this.status,
async (status) => {
if ([ConnectionStatus.CONNECTING, ConnectionStatus.DISCONNECTING].includes(status)) {
this.resetLocation()
}
if ([ConnectionStatus.NOT_CONNECTED, ConnectionStatus.CONNECTED].includes(status)) {
await this.resolveLocation()
}
},
)
reaction(
() => this.status,
(status) => {
ipcRenderer.send(MainIpcListenChannels.ConnectionStatus, status)
},
{ name: "Notify tray with new connection status" },
)
reaction(
() => this.root.connection.status,
(status) => this.root.navigation.navigateOnConnectionStatus(status),
)
reaction(
() => this.root.daemon.status,
async (status) => {
if (status === DaemonStatusType.Up) {
await this.resolveNATType()
}
},
)
reaction(
() => this.root.config.autoNATCompatibility,
async () => {
await this.resolveNATType()
},
)
window.addEventListener("online", async () => {
log.info("Network connection restored")
await this.resolveNATType()
})
window.addEventListener("offline", async () => {
log.info("Network connection lost")
await this.resolveNATType()
})
}