Merge pull request #221 from gnanam1990/fix/keyboard-freeze-mcp-notifications
fix: prevent keyboard freeze when MCP notification effects fire
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import type * as React from 'react';
|
import type * as React from 'react';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
import { useAppStateStore, useSetAppState } from 'src/state/AppState.js';
|
import { useAppStateStore, useSetAppState } from 'src/state/AppState.js';
|
||||||
|
import { logError } from '../utils/log.js';
|
||||||
import type { Theme } from '../utils/theme.js';
|
import type { Theme } from '../utils/theme.js';
|
||||||
type Priority = 'low' | 'medium' | 'high' | 'immediate';
|
type Priority = 'low' | 'medium' | 'high' | 'immediate';
|
||||||
type BaseNotification = {
|
type BaseNotification = {
|
||||||
@@ -44,6 +45,7 @@ export function useNotifications(): {
|
|||||||
|
|
||||||
// Process queue when current notification finishes or queue changes
|
// Process queue when current notification finishes or queue changes
|
||||||
const processQueue = useCallback(() => {
|
const processQueue = useCallback(() => {
|
||||||
|
try {
|
||||||
setAppState(prev => {
|
setAppState(prev => {
|
||||||
const next = getNext(prev.notifications.queue);
|
const next = getNext(prev.notifications.queue);
|
||||||
if (prev.notifications.current !== null || !next) {
|
if (prev.notifications.current !== null || !next) {
|
||||||
@@ -74,8 +76,12 @@ export function useNotifications(): {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logError(error);
|
||||||
|
}
|
||||||
}, [setAppState]);
|
}, [setAppState]);
|
||||||
const addNotification = useCallback<AddNotificationFn>((notif: Notification) => {
|
const addNotification = useCallback<AddNotificationFn>((notif: Notification) => {
|
||||||
|
try {
|
||||||
// Handle immediate priority notifications
|
// Handle immediate priority notifications
|
||||||
if (notif.priority === 'immediate') {
|
if (notif.priority === 'immediate') {
|
||||||
// Clear any existing timeout since we're showing a new immediate notification
|
// Clear any existing timeout since we're showing a new immediate notification
|
||||||
@@ -189,8 +195,12 @@ export function useNotifications(): {
|
|||||||
|
|
||||||
// Process queue after adding the notification
|
// Process queue after adding the notification
|
||||||
processQueue();
|
processQueue();
|
||||||
|
} catch (error) {
|
||||||
|
logError(error);
|
||||||
|
}
|
||||||
}, [setAppState, processQueue]);
|
}, [setAppState, processQueue]);
|
||||||
const removeNotification = useCallback<RemoveNotificationFn>((key: string) => {
|
const removeNotification = useCallback<RemoveNotificationFn>((key: string) => {
|
||||||
|
try {
|
||||||
setAppState(prev => {
|
setAppState(prev => {
|
||||||
const isCurrent = prev.notifications.current?.key === key;
|
const isCurrent = prev.notifications.current?.key === key;
|
||||||
const inQueue = prev.notifications.queue.some(n => n.key === key);
|
const inQueue = prev.notifications.queue.some(n => n.key === key);
|
||||||
@@ -210,6 +220,9 @@ export function useNotifications(): {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
processQueue();
|
processQueue();
|
||||||
|
} catch (error) {
|
||||||
|
logError(error);
|
||||||
|
}
|
||||||
}, [setAppState, processQueue]);
|
}, [setAppState, processQueue]);
|
||||||
|
|
||||||
// Process queue on mount if there are notifications in the initial state.
|
// Process queue on mount if there are notifications in the initial state.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { c as _c } from "react-compiler-runtime";
|
import { c as _c } from "react-compiler-runtime";
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { logError } from '../../utils/log.js';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useNotifications } from 'src/context/notifications.js';
|
import { useNotifications } from 'src/context/notifications.js';
|
||||||
import { getIsRemoteMode } from '../../bootstrap/state.js';
|
import { getIsRemoteMode } from '../../bootstrap/state.js';
|
||||||
@@ -23,6 +24,7 @@ export function useMcpConnectivityStatus(t0) {
|
|||||||
let t3;
|
let t3;
|
||||||
if ($[0] !== addNotification || $[1] !== mcpClients) {
|
if ($[0] !== addNotification || $[1] !== mcpClients) {
|
||||||
t2 = () => {
|
t2 = () => {
|
||||||
|
try {
|
||||||
if (getIsRemoteMode()) {
|
if (getIsRemoteMode()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -61,6 +63,9 @@ export function useMcpConnectivityStatus(t0) {
|
|||||||
priority: "medium"
|
priority: "medium"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logError(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
t3 = [addNotification, mcpClients];
|
t3 = [addNotification, mcpClients];
|
||||||
$[0] = addNotification;
|
$[0] = addNotification;
|
||||||
|
|||||||
@@ -433,6 +433,8 @@ const reconciler = createReconciler<
|
|||||||
scheduleTimeout: setTimeout,
|
scheduleTimeout: setTimeout,
|
||||||
cancelTimeout: clearTimeout,
|
cancelTimeout: clearTimeout,
|
||||||
noTimeout: -1,
|
noTimeout: -1,
|
||||||
|
supportsMicrotasks: true,
|
||||||
|
scheduleMicrotask: queueMicrotask,
|
||||||
getCurrentUpdatePriority: () => dispatcher.currentUpdatePriority,
|
getCurrentUpdatePriority: () => dispatcher.currentUpdatePriority,
|
||||||
beforeActiveInstanceBlur() {},
|
beforeActiveInstanceBlur() {},
|
||||||
afterActiveInstanceBlur() {},
|
afterActiveInstanceBlur() {},
|
||||||
|
|||||||
@@ -12,9 +12,17 @@ const originalEnv = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
if (originalEnv.CLAUDE_CODE_USE_OPENAI === undefined) {
|
||||||
|
delete process.env.CLAUDE_CODE_USE_OPENAI
|
||||||
|
} else {
|
||||||
process.env.CLAUDE_CODE_USE_OPENAI = originalEnv.CLAUDE_CODE_USE_OPENAI
|
process.env.CLAUDE_CODE_USE_OPENAI = originalEnv.CLAUDE_CODE_USE_OPENAI
|
||||||
|
}
|
||||||
|
if (originalEnv.CLAUDE_CODE_MAX_OUTPUT_TOKENS === undefined) {
|
||||||
|
delete process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS
|
||||||
|
} else {
|
||||||
process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS =
|
process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS =
|
||||||
originalEnv.CLAUDE_CODE_MAX_OUTPUT_TOKENS
|
originalEnv.CLAUDE_CODE_MAX_OUTPUT_TOKENS
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
test('deepseek-chat uses provider-specific context and output caps', () => {
|
test('deepseek-chat uses provider-specific context and output caps', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user