coze-studio/frontend/packages/project-ide/view/src/view-manager.tsx

114 lines
3.8 KiB
TypeScript

/*
* 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 { mergeWith } from 'lodash';
import { inject, injectable, named } from 'inversify';
import { ContributionProvider } from '@flowgram-adapter/common';
import { OpenerService } from '@coze-project-ide/core';
import { WidgetManager } from './widget-manager';
import { DebugBarWidget } from './widget/react-widgets/debug-bar-widget';
import { ViewRenderer } from './view-renderer';
import { LayoutPanelType, type ViewPluginOptions } from './types';
import { ApplicationShell, LayoutRestorer } from './shell';
import { ViewContribution } from './contributions/view-contribution';
import { ViewOptions } from './constants/view-options';
@injectable()
export class ViewManager {
@inject(ContributionProvider)
@named(ViewContribution)
viewContributions: ContributionProvider<ViewContribution>;
// 通过 widgetManager 进行注入
@inject(WidgetManager) widgetManager: WidgetManager;
@inject(ViewOptions) options: ViewOptions;
@inject(ApplicationShell) shell: ApplicationShell;
@inject(ViewRenderer) viewRenderer: ViewRenderer;
@inject(LayoutRestorer) layoutRestorer: LayoutRestorer;
@inject(OpenerService) openerService: OpenerService;
@inject(DebugBarWidget) debugWidget: DebugBarWidget;
async init(viewOptions: ViewPluginOptions) {
this.mergeOptions(viewOptions);
const { widgetFactories } = viewOptions;
this.widgetManager.init(widgetFactories);
this.layoutRestorer.init(viewOptions);
await this.shell.init({
createLayout: viewOptions.customLayout,
splitScreenConfig: viewOptions.presetConfig?.splitScreenConfig,
disableFullScreen: viewOptions.presetConfig?.disableFullScreen,
});
if (this.options?.defaultLayoutData?.debugBar) {
this.debugWidget.initContent(viewOptions.defaultLayoutData?.debugBar);
}
}
async attach(viewOptions: ViewPluginOptions) {
await this.layoutRestorer.restoreLayout();
viewOptions.defaultLayoutData?.defaultWidgets?.forEach(uri => {
this.openerService.open(uri);
});
// activityBar 由内部自定义,比较特殊
const activityBar = this.shell.activityBarWidget;
this.viewRenderer.addReactPortal(activityBar);
activityBar?.initView?.(
viewOptions.defaultLayoutData?.activityBarItems || [],
);
this.shell.addWidget(activityBar, {
area: LayoutPanelType.ACTIVITY_BAR,
});
const statusBar = this.shell.statusBarWidget;
if (statusBar) {
this.viewRenderer.addReactPortal(statusBar);
statusBar.initView(viewOptions.defaultLayoutData?.statusBarItems || []);
this.shell.addWidget(statusBar, {
area: LayoutPanelType.STATUS_BAR,
});
}
}
private mergeOptions(viewOptions: ViewPluginOptions) {
this.viewContributions.getContributions().forEach(contribution => {
contribution.registerView({
register: options => {
mergeWith(viewOptions, options, (objValue, srcValue, key) => {
if (
[
'widgetFactories',
'activityBarItems',
'statusBarItems',
'defaultWidgets',
].includes(key)
) {
return [...(objValue || []), ...srcValue];
}
});
},
});
});
}
}