Develop (#55)
feat: optimize dashboard/search UX and simplify extension architecture Redesign Dashboard with compact tool grid and recently used tools Improve TopBar search UX with Cmd/Ctrl+K shortcut and better history navigation Reorganize project structure into src/ Migrate i18n from react-i18next to chrome.i18n Remove runtime language switch and settings page Remove HTML/Markdown conversion tools Clean up unused code, dead animations, redundant comments, and imports Improve component consistency with shadcn/ui patterns Replace hardcoded strings/colors with i18n tokens and theme tokens Add comprehensive project documentation and coding standards Fix CI artifact upload workflow and multiple TypeScript/test issues Includes various refactors, UI polish, i18n cleanup, CI improvements, and maintenance updates across the codebase.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { defineExtensionMessaging } from '@webext-core/messaging';
|
||||
|
||||
export enum MessageAction {
|
||||
RELOAD_TAB = 'reloadTab',
|
||||
SIDE_PANEL_STATE_CHANGED = 'sidePanelStateChanged',
|
||||
CONTEXT_MENU_CLICKED = 'contextMenuClicked',
|
||||
RESTORE_RIGHT_CLICK = 'restoreRightClick',
|
||||
QUERY_RIGHT_CLICK_STATUS = 'queryRightClickStatus',
|
||||
INJECT_MAIN_WORLD_SCRIPT = 'injectMainWorldScript',
|
||||
}
|
||||
|
||||
export interface MessageResponse {
|
||||
success: boolean;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface ContextMenuClickedPayload {
|
||||
featureKey: string;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export interface ProtocolMap {
|
||||
[MessageAction.RELOAD_TAB](data: { tabId: number; delay?: number }): MessageResponse;
|
||||
[MessageAction.SIDE_PANEL_STATE_CHANGED](data: { isOpen: boolean }): void;
|
||||
[MessageAction.CONTEXT_MENU_CLICKED](data: ContextMenuClickedPayload): void;
|
||||
[MessageAction.RESTORE_RIGHT_CLICK](data: undefined): MessageResponse & { restored: boolean };
|
||||
[MessageAction.QUERY_RIGHT_CLICK_STATUS](
|
||||
data: undefined,
|
||||
): MessageResponse & { restored: boolean };
|
||||
[MessageAction.INJECT_MAIN_WORLD_SCRIPT](data: undefined): MessageResponse;
|
||||
}
|
||||
|
||||
export const { sendMessage, onMessage } = defineExtensionMessaging<ProtocolMap>();
|
||||
|
||||
export async function sendMessageToContent<K extends keyof ProtocolMap>(
|
||||
action: K,
|
||||
...args: Parameters<ProtocolMap[K]>[0] extends undefined
|
||||
? []
|
||||
: [data: Parameters<ProtocolMap[K]>[0]]
|
||||
): Promise<ReturnType<ProtocolMap[K]>> {
|
||||
try {
|
||||
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||
if (!tab?.id) {
|
||||
console.warn(`[Messaging] 无法获取当前标签页,无法发送动作: ${action}`);
|
||||
return { success: false, message: '无法获取当前标签页' } as ReturnType<ProtocolMap[K]>;
|
||||
}
|
||||
|
||||
const data = args.length > 0 ? args[0] : undefined;
|
||||
|
||||
const response = await (
|
||||
sendMessage as (
|
||||
type: K,
|
||||
data: Parameters<ProtocolMap[K]>[0],
|
||||
arg?: number,
|
||||
) => Promise<ReturnType<ProtocolMap[K]>>
|
||||
)(action, data as Parameters<ProtocolMap[K]>[0], tab.id);
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
||||
console.error(`[Messaging] 向内容脚本发送消息失败 [Action: ${action}]:`, errorMsg);
|
||||
|
||||
if (errorMsg.includes('Could not establish connection')) {
|
||||
return { success: false, message: '无法连接到网页,请刷新页面后再试' } as ReturnType<
|
||||
ProtocolMap[K]
|
||||
>;
|
||||
}
|
||||
if (errorMsg.includes('No response')) {
|
||||
return { success: false, message: '网页响应超时,请重试' } as ReturnType<ProtocolMap[K]>;
|
||||
}
|
||||
|
||||
return { success: false, message: `通信失败: ${errorMsg}` } as ReturnType<ProtocolMap[K]>;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user