coze-studio/frontend/packages/project-ide/view/src/services/view-service.ts

223 lines
5.7 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 { inject, injectable } from 'inversify';
import { Emitter } from '@flowgram-adapter/common';
import { type URI } from '@coze-project-ide/core';
import { WidgetOpenHandler } from '../widget/widget-open-handler';
import { type ReactWidget } from '../widget/react-widget';
import { type FlowDockPanel } from '../widget/dock-panel';
import { type CustomTitleType, LayoutPanelType } from '../types';
import { ApplicationShell } from '../shell';
import { type DockLayout } from '../lumino/widgets';
import { ALL_PANEL_TYPES } from '../constants/view';
@injectable()
export class ViewService {
@inject(ApplicationShell) shell: ApplicationShell;
@inject(WidgetOpenHandler) protected readonly openHandler: WidgetOpenHandler;
private isFullScreenMode = false;
private onFullScreenModeChangeEmitter = new Emitter<boolean>();
onFullScreenModeChange = this.onFullScreenModeChangeEmitter.event;
private prevPanelMap = new Map<LayoutPanelType, boolean>();
/**
* Evoke the bottom panel
*/
toggleBottomLayout() {
this.shell.bottomSplitLayout.setRelativeSizes([0.7, 0.3]);
}
/**
* Hide bottom panel
*/
hideBottomLayout() {
this.shell.bottomSplitLayout.setRelativeSizes([1, 0]);
}
/**
* Get all open tab titles
*/
getOpenTitles() {
let titles: CustomTitleType[] = [];
const tabBars = (
this.shell.mainPanel.layout as unknown as DockLayout
).tabBars();
for (const tabBar of tabBars) {
titles = titles.concat(tabBar.titles as CustomTitleType[]);
}
return titles;
}
/**
* Get all tabs currently open in the panel
*/
getAllTabsFromArea(
area: LayoutPanelType.MAIN_PANEL | LayoutPanelType.BOTTOM_PANEL,
) {
const widgets =
area === LayoutPanelType.MAIN_PANEL
? this.shell.mainPanel.widgets()
: this.shell.bottomPanel.widgets();
const dockPanels: any[] = [];
for (const dockPanel of widgets) {
dockPanels.push(dockPanel);
}
return dockPanels;
}
/**
* Close all tabs except the current tab
*/
closeOtherTabs(dispose = true) {
try {
const parentWidget = this.shell.currentWidget?.parent;
if (!parentWidget) {
return;
}
const widgets = (parentWidget as FlowDockPanel).tabBars();
for (const customTabBar of widgets) {
[...customTabBar.titles].map(title => {
if (title.label !== customTabBar.currentTitle?.label) {
customTabBar.removeTab(title);
if (dispose) {
title.owner.dispose();
}
}
});
}
} catch (e) {
console.error(e);
}
}
/**
* Open the next tab in the main panel
*/
openNextTab() {
const tabBars = (
this.shell.mainPanel.layout as unknown as DockLayout
).tabBars();
for (const tabbar of tabBars) {
const idx = tabbar.titles.findIndex(
title => title.owner === this.shell.currentWidget,
);
if (idx !== -1) {
const nextUri = (
tabbar.titles[(idx + 1) % tabbar.titles.length].owner as ReactWidget
)?.getResourceURI();
if (nextUri) {
this.openHandler.open(nextUri);
}
}
}
}
/**
* Open the previous tab of the main panel
*/
openLastTab() {
const tabBars = (
this.shell.mainPanel.layout as unknown as DockLayout
).tabBars();
for (const tabbar of tabBars) {
const idx = tabbar.titles.findIndex(
title => title.owner === this.shell.currentWidget,
);
if (idx !== -1) {
const nextUri = (
tabbar.titles[(idx - 1 + tabbar.titles.length) % tabbar.titles.length]
.owner as ReactWidget
)?.getResourceURI();
if (nextUri) {
this.openHandler.open(nextUri);
}
}
}
}
/**
* Enable full screen mode
*/
enableFullScreenMode() {
if (this.isFullScreenMode) {
return;
}
ALL_PANEL_TYPES.forEach(type => {
if (type !== LayoutPanelType.MAIN_PANEL) {
const panel = this.shell.getPanelFromArea(type);
this.prevPanelMap.set(type, panel.isHidden);
panel.hide();
}
});
this.isFullScreenMode = true;
this.onFullScreenModeChangeEmitter.fire(true);
}
/**
* Turn off full screen mode
*/
disableFullScreenMode() {
if (!this.isFullScreenMode) {
return;
}
ALL_PANEL_TYPES.forEach(type => {
if (type !== LayoutPanelType.MAIN_PANEL) {
const panel = this.shell.getPanelFromArea(type);
const isHidden = Boolean(this.prevPanelMap.get(type));
panel.setHidden(isHidden);
}
});
this.isFullScreenMode = false;
this.onFullScreenModeChangeEmitter.fire(false);
}
/**
* full screen mode toggle
*/
switchFullScreenMode() {
if (!this.isFullScreenMode) {
this.enableFullScreenMode();
} else {
this.disableFullScreenMode();
}
}
/**
* Set the current activityBar item
*/
setActivityBarUri(uri: URI) {
this.shell.activityBarWidget.setCurrentUri(uri);
}
/**
* Get the current activityBar active item
*/
get activityBarUri() {
return this.shell.activityBarWidget.currentUri;
}
}