feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
36
frontend/packages/project-ide/framework/src/hooks/index.ts
Normal file
36
frontend/packages/project-ide/framework/src/hooks/index.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { useSpaceId } from './use-space-id';
|
||||
export { useProjectIDEServices } from './use-project-ide-services';
|
||||
export { useCurrentWidgetContext } from './use-current-widget-context';
|
||||
export { useActivateWidgetContext } from './use-activate-widget-context';
|
||||
export { useIDENavigate } from './use-ide-navigate';
|
||||
export { useCurrentModeType } from './use-current-mode-type';
|
||||
export { useProjectId } from './use-project-id';
|
||||
export { useSplitScreenArea } from './use-current-split-screen';
|
||||
export { useTitle } from './use-title';
|
||||
export { useIDELocation, useIDEParams } from './use-ide-location';
|
||||
export { useIDEServiceInBiz } from './use-ide-service-in-biz';
|
||||
export { useShortcuts } from './use-shortcuts';
|
||||
export { useCommitVersion } from './use-commit-version';
|
||||
export { useWsListener } from './use-ws-listener';
|
||||
export {
|
||||
useSendMessageEvent,
|
||||
useListenMessageEvent,
|
||||
} from './use-message-event';
|
||||
export { useViewService } from './use-view-service';
|
||||
export { useGetUIWidgetFromId } from './use-get-ui-widget-from-id';
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
useCurrentWidgetFromArea,
|
||||
LayoutPanelType,
|
||||
} from '@coze-project-ide/client';
|
||||
|
||||
import { type ProjectIDEWidget } from '@/widgets/project-ide-widget';
|
||||
import { type WidgetContext } from '@/context/widget-context';
|
||||
|
||||
/**
|
||||
* 用于提供当前 focus 的 widget 上下文
|
||||
*/
|
||||
export const useActivateWidgetContext = (): WidgetContext => {
|
||||
const currentWidget = useCurrentWidgetFromArea(LayoutPanelType.MAIN_PANEL);
|
||||
return (currentWidget as ProjectIDEWidget)?.context;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useIDEGlobalStore } from '../context';
|
||||
|
||||
export const useCommitVersion = () => {
|
||||
// 内置了 shallow 操作,无需 useShallow
|
||||
// eslint-disable-next-line @coze-arch/zustand/prefer-shallow
|
||||
const { version, patch } = useIDEGlobalStore(store => ({
|
||||
version: store.version,
|
||||
patch: store.patch,
|
||||
}));
|
||||
|
||||
return {
|
||||
version,
|
||||
patch,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { type ModeType } from '../types';
|
||||
import { UI_BUILDER_URI } from '../constants';
|
||||
|
||||
export const useCurrentModeType = () => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const type: ModeType = useMemo(() => {
|
||||
if (pathname.includes(UI_BUILDER_URI.path.toString())) {
|
||||
return 'ui-builder';
|
||||
}
|
||||
return 'dev';
|
||||
}, [pathname]);
|
||||
|
||||
return type;
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
ApplicationShell,
|
||||
useIDEService,
|
||||
type URI,
|
||||
type DockLayout,
|
||||
type ReactWidget,
|
||||
type TabBar,
|
||||
type Widget,
|
||||
} from '@coze-project-ide/client';
|
||||
|
||||
import { compareURI } from '@/utils';
|
||||
|
||||
type Area = 'left' | 'right';
|
||||
|
||||
const getTabArea = (shell: ApplicationShell, uri?: URI): Area | undefined => {
|
||||
let currentTabIndex = -1;
|
||||
const area = (shell.mainPanel?.layout as DockLayout)?.saveLayout?.().main;
|
||||
const children = (area as DockLayout.ISplitAreaConfig)?.children || [area];
|
||||
|
||||
children.forEach((child, idx) => {
|
||||
const containCurrent =
|
||||
uri &&
|
||||
((child as DockLayout.ITabAreaConfig)?.widgets || []).some(
|
||||
widget => (widget as ReactWidget).uri?.toString?.() === uri.toString(),
|
||||
);
|
||||
if (containCurrent) {
|
||||
currentTabIndex = idx;
|
||||
}
|
||||
});
|
||||
|
||||
// 右边分屏不展示 hover icon
|
||||
if (children?.length === 1) {
|
||||
return undefined;
|
||||
} else if (currentTabIndex === 1) {
|
||||
return 'right';
|
||||
} else {
|
||||
return 'left';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前 uri 的资源在哪个分屏下
|
||||
* left: 左边分屏
|
||||
* right: 右边分屏
|
||||
* undefined: 未分屏
|
||||
*/
|
||||
export const useSplitScreenArea = (
|
||||
uri?: URI,
|
||||
tabBar?: TabBar<Widget>,
|
||||
): Area | undefined => {
|
||||
const shell = useIDEService<ApplicationShell>(ApplicationShell);
|
||||
|
||||
const [area, setArea] = useState(getTabArea(shell, uri));
|
||||
|
||||
useEffect(() => {
|
||||
setArea(getTabArea(shell, uri));
|
||||
const listener = () => {
|
||||
// 本次 uri 是否在当前 tab,不是不执行
|
||||
// 分屏过程中会出现中间态,布局变更时盲目执行会导致时序异常问题
|
||||
const uriInCurrentTab = tabBar?.titles.some(title =>
|
||||
compareURI((title.owner as ReactWidget)?.uri, uri),
|
||||
);
|
||||
if (uriInCurrentTab) {
|
||||
setArea(getTabArea(shell, uri));
|
||||
}
|
||||
};
|
||||
shell.mainPanel.layoutModified.connect(listener);
|
||||
return () => {
|
||||
shell.mainPanel.layoutModified.disconnect(listener);
|
||||
};
|
||||
}, [uri?.toString?.()]);
|
||||
|
||||
return area;
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCurrentWidget } from '@coze-project-ide/client';
|
||||
|
||||
import { type ProjectIDEWidget } from '@/widgets/project-ide-widget';
|
||||
|
||||
import { type WidgetContext } from '../context/widget-context';
|
||||
|
||||
/**
|
||||
* 获取当前的 WidgetContext
|
||||
* 在 registry 的 renderContent 内调用
|
||||
*/
|
||||
export function useCurrentWidgetContext<T>(): WidgetContext<T> {
|
||||
const currentWidget = useCurrentWidget() as ProjectIDEWidget;
|
||||
if (!currentWidget.context) {
|
||||
throw new Error(
|
||||
'[useWidgetContext] Undefined widgetContext from ide context',
|
||||
);
|
||||
}
|
||||
return currentWidget.context as WidgetContext<T>;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { URI, useIDEService, WidgetManager } from '@coze-project-ide/client';
|
||||
|
||||
import { type ProjectIDEWidget } from '../widgets/project-ide-widget';
|
||||
import { URI_SCHEME } from '../constants';
|
||||
|
||||
export const useGetUIWidgetFromId = (
|
||||
value: string,
|
||||
): ProjectIDEWidget | undefined => {
|
||||
const widgetManager = useIDEService<WidgetManager>(WidgetManager);
|
||||
const uri = new URI(`${URI_SCHEME}://${value}`);
|
||||
const widget = widgetManager.getWidgetFromURI(uri) as ProjectIDEWidget;
|
||||
return widget;
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
||||
|
||||
import { type URI, useCurrentWidget } from '@coze-project-ide/client';
|
||||
|
||||
import { type ProjectIDEWidget } from '../widgets/project-ide-widget';
|
||||
|
||||
type ActivateCallback = (widget: ProjectIDEWidget) => void;
|
||||
|
||||
interface WidgetLocation {
|
||||
uri: URI;
|
||||
pathname: string;
|
||||
params: { [key: string]: string | undefined };
|
||||
}
|
||||
|
||||
const genLocationByURI = (uri: URI): WidgetLocation => ({
|
||||
uri,
|
||||
pathname: uri.path.toString(),
|
||||
params: uri.queryObject,
|
||||
});
|
||||
|
||||
const useCurrentWidgetActivate = (cb: ActivateCallback) => {
|
||||
const currentWidget = useCurrentWidget() as ProjectIDEWidget;
|
||||
useLayoutEffect(() => {
|
||||
const dispose = currentWidget.onActivate(() => {
|
||||
cb(currentWidget);
|
||||
});
|
||||
return () => dispose.dispose();
|
||||
}, [currentWidget, cb]);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前 widget 的 location
|
||||
*/
|
||||
export const useIDELocation = () => {
|
||||
const currentWidget = useCurrentWidget() as ProjectIDEWidget;
|
||||
const [location, setLocation] = useState(
|
||||
genLocationByURI(currentWidget.uri!),
|
||||
);
|
||||
const uriRef = useRef(currentWidget.uri?.toString());
|
||||
|
||||
const callback = useCallback<ActivateCallback>(
|
||||
widget => {
|
||||
if (uriRef.current !== widget.uri?.toString()) {
|
||||
uriRef.current = widget.uri?.toString();
|
||||
setLocation(genLocationByURI(widget.uri!));
|
||||
}
|
||||
},
|
||||
[setLocation, uriRef],
|
||||
);
|
||||
|
||||
useCurrentWidgetActivate(callback);
|
||||
|
||||
return location;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前 widget 的 query 参数
|
||||
*/
|
||||
export const useIDEParams = () => {
|
||||
const currentWidget = useCurrentWidget() as ProjectIDEWidget;
|
||||
const [params, setParams] = useState(currentWidget.uri?.queryObject || {});
|
||||
const queryRef = useRef(currentWidget.uri?.query);
|
||||
|
||||
const callback = useCallback<ActivateCallback>(
|
||||
widget => {
|
||||
const query = widget.uri?.query;
|
||||
if (queryRef.current !== query) {
|
||||
queryRef.current = query;
|
||||
setParams(widget.uri?.queryObject || {});
|
||||
}
|
||||
},
|
||||
[queryRef, setParams],
|
||||
);
|
||||
|
||||
useCurrentWidgetActivate(callback);
|
||||
|
||||
return params;
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useNavigate, type NavigateOptions } from 'react-router-dom';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { URI } from '@coze-project-ide/client';
|
||||
|
||||
import { addPreservedSearchParams } from '../utils';
|
||||
import { URI_SCHEME, UI_BUILDER_URI } from '../constants';
|
||||
import { useSpaceId } from './use-space-id';
|
||||
import { useProjectIDEServices } from './use-project-ide-services';
|
||||
import { useProjectId } from './use-project-id';
|
||||
|
||||
export const useIDENavigate = () => {
|
||||
const { view } = useProjectIDEServices();
|
||||
const spaceId = useSpaceId();
|
||||
const projectId = useProjectId();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
/**
|
||||
* value(string): /:resourceType/:resourceId?a=a&b=b
|
||||
*/
|
||||
const IDENavigate = useCallback(
|
||||
(value: string, options?: NavigateOptions) => {
|
||||
const url = `/space/${spaceId}/project-ide/${projectId}${value}`;
|
||||
const uri = new URI(`${URI_SCHEME}://${value}`);
|
||||
const isUIBuilder = uri.displayName === UI_BUILDER_URI.displayName;
|
||||
if (value && value !== '/' && !isUIBuilder) {
|
||||
// 调用 openService
|
||||
view.open(uri);
|
||||
} else {
|
||||
// 如果没有要打开的 widget,就只打开主面板
|
||||
view.openPanel(isUIBuilder ? 'ui-builder' : 'dev');
|
||||
}
|
||||
navigate(addPreservedSearchParams(url), options);
|
||||
},
|
||||
[spaceId, projectId, view, navigate],
|
||||
);
|
||||
|
||||
return IDENavigate;
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type interfaces } from 'inversify';
|
||||
import { useIDEContainer } from '@coze-project-ide/client';
|
||||
|
||||
/**
|
||||
* 获取 IDE 的 IOC 模块
|
||||
* 和 flow-ide/client 包内容相同,但可以支持在业务侧如 workflow 内调用
|
||||
* @param identifier
|
||||
*/
|
||||
export function useIDEServiceInBiz<T>(
|
||||
identifier: interfaces.ServiceIdentifier,
|
||||
): T | undefined {
|
||||
const container = useIDEContainer();
|
||||
if (container.isBound(identifier)) {
|
||||
return container.get(identifier) as T;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { URI, useIDEService } from '@coze-project-ide/client';
|
||||
|
||||
import { getURLByURI } from '../utils';
|
||||
import { MessageEventService, type MessageEvent } from '../services';
|
||||
import { URI_SCHEME } from '../constants';
|
||||
import { useIDENavigate } from './use-ide-navigate';
|
||||
|
||||
export const useMessageEventService = () =>
|
||||
useIDEService<MessageEventService>(MessageEventService);
|
||||
|
||||
/**
|
||||
* 获取向 widget 发送信息函数的 hooks
|
||||
*/
|
||||
export const useSendMessageEvent = () => {
|
||||
const messageEventService = useMessageEventService();
|
||||
const navigate = useIDENavigate();
|
||||
|
||||
/**
|
||||
* 向以 uri 为索引的 widget 发送信息
|
||||
*/
|
||||
const send = useCallback(
|
||||
<T>(target: string | URI, data: MessageEvent<T>) => {
|
||||
const uri =
|
||||
typeof target === 'string'
|
||||
? new URI(`${URI_SCHEME}://${target}`)
|
||||
: target;
|
||||
messageEventService.send(uri, data);
|
||||
},
|
||||
[messageEventService],
|
||||
);
|
||||
|
||||
/**
|
||||
* 向以 uri 为索引的 widget 发送信息,并且打开/激活此 widget
|
||||
* 此函数比较常用
|
||||
*/
|
||||
const sendOpen = useCallback(
|
||||
<T>(target: string | URI, data: MessageEvent<T>) => {
|
||||
const uri =
|
||||
typeof target === 'string'
|
||||
? new URI(`${URI_SCHEME}://${target}`)
|
||||
: target;
|
||||
messageEventService.send(uri, data);
|
||||
navigate(getURLByURI(uri));
|
||||
},
|
||||
[messageEventService, navigate],
|
||||
);
|
||||
|
||||
return { send, sendOpen };
|
||||
};
|
||||
|
||||
/**
|
||||
* 监听向指定 uri 对应的唯一 widget 发送消息的 hook
|
||||
* 监听消息的 widget 一定是知道 this.uri,所以入参无须支持 string
|
||||
* 注:虽然 widget.uri 的值是会变得,但其 withoutQuery().toString() 一定是不变的,所以 uri 可以认定为不变
|
||||
*/
|
||||
export const useListenMessageEvent = (
|
||||
uri: URI,
|
||||
cb: (e: MessageEvent) => void,
|
||||
) => {
|
||||
const messageEventService = useMessageEventService();
|
||||
// 尽管 uri 对应的唯一 key 不会变化,但 uri 内存地址仍然会变化,这里显式的固化 uri 的不变性
|
||||
const uriRef = useRef(uri);
|
||||
|
||||
// 保证 callback 函数的可变性
|
||||
const listener = useMemoizedFn(() => {
|
||||
const queue = messageEventService.on(uri);
|
||||
queue.forEach(cb);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// 组件挂在时去队列中取一次,有可能在组件未挂载前已经被发送了消息
|
||||
listener();
|
||||
|
||||
const disposable = messageEventService.onSend(e => {
|
||||
if (messageEventService.compare(e.uri, uriRef.current)) {
|
||||
listener();
|
||||
}
|
||||
});
|
||||
return () => disposable.dispose();
|
||||
}, [messageEventService, listener, uriRef]);
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useIDEGlobalContext } from '../context';
|
||||
|
||||
export const useProjectId = () => {
|
||||
const store = useIDEGlobalContext();
|
||||
const projectId = store(state => state.projectId);
|
||||
|
||||
return projectId;
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useIDEService } from '@coze-project-ide/client';
|
||||
|
||||
import { ProjectIDEServices } from '../plugins/create-preset-plugin/project-ide-services';
|
||||
|
||||
export const useProjectIDEServices = (): ProjectIDEServices => {
|
||||
const projectIDEServices =
|
||||
useIDEService<ProjectIDEServices>(ProjectIDEServices);
|
||||
|
||||
return projectIDEServices;
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
useIDEService,
|
||||
ShortcutsService,
|
||||
CommandRegistry,
|
||||
} from '@coze-project-ide/client';
|
||||
|
||||
export const useShortcuts = (commandId: string) => {
|
||||
const commandRegistry = useIDEService<CommandRegistry>(CommandRegistry);
|
||||
const shortcutsService = useIDEService<ShortcutsService>(ShortcutsService);
|
||||
|
||||
const shortcut = shortcutsService.getShortcutByCommandId(commandId);
|
||||
const keybinding = shortcut.map(item => item.join(' ')).join('/');
|
||||
const label = commandRegistry.getCommand(commandId)?.label;
|
||||
|
||||
return {
|
||||
keybinding,
|
||||
label,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useIDEGlobalContext } from '../context';
|
||||
|
||||
export const useSpaceId = () => {
|
||||
const store = useIDEGlobalContext();
|
||||
const spaceId = store(state => state.spaceId);
|
||||
|
||||
return spaceId;
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useCurrentWidgetContext } from './use-current-widget-context';
|
||||
|
||||
export const useTitle = () => {
|
||||
const currentWidgetContext = useCurrentWidgetContext();
|
||||
const { widget } = currentWidgetContext;
|
||||
const [title, setTitle] = useState(widget.getTitle());
|
||||
useEffect(() => {
|
||||
const disposable = widget.onTitleChanged(_title => {
|
||||
setTitle(_title);
|
||||
});
|
||||
return () => {
|
||||
disposable?.dispose?.();
|
||||
};
|
||||
}, []);
|
||||
return title;
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ViewService } from '@/plugins/create-preset-plugin/view-service';
|
||||
|
||||
import { useProjectIDEServices } from './use-project-ide-services';
|
||||
|
||||
/**
|
||||
* 获取 ProjectIDE 所有视图操作
|
||||
*/
|
||||
export const useViewService = (): ViewService => {
|
||||
const projectIDEServices = useProjectIDEServices();
|
||||
return projectIDEServices.view;
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
import { useIDEService } from '@coze-project-ide/client';
|
||||
|
||||
import { type WsMessageProps } from '@/types';
|
||||
import { WsService } from '@/services';
|
||||
|
||||
export const useWsListener = (listener: (props: WsMessageProps) => void) => {
|
||||
const wsService = useIDEService<WsService>(WsService);
|
||||
|
||||
useEffect(() => {
|
||||
const disposable = wsService.onMessageSend(listener);
|
||||
return () => {
|
||||
disposable.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const send = useCallback(
|
||||
data => {
|
||||
wsService.send(data);
|
||||
},
|
||||
[wsService],
|
||||
);
|
||||
|
||||
return {
|
||||
send,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user