Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions emain/emain-window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,30 +282,32 @@ export class WaveBrowserWindow extends BaseWindow {
await this.queueTabSwitch(tabView, tabInitialized);
}

async setActiveTab(tabId: string) {
console.log("setActiveTab", this);
const workspace = await WorkspaceService.GetWorkspace(this.workspaceId);
await WorkspaceService.SetActiveTab(workspace.oid, tabId);
async setActiveTab(tabId: string, setInBackend: boolean) {
console.log("setActiveTab", tabId, this.waveWindowId, this.workspaceId, setInBackend);
if (setInBackend) {
await WorkspaceService.SetActiveTab(this.workspaceId, tabId);
}
const fullConfig = await FileService.GetFullConfig();
const [tabView, tabInitialized] = getOrCreateWebViewForTab(fullConfig, tabId);
await this.queueTabSwitch(tabView, tabInitialized);
}

async createTab() {
const tabId = await WorkspaceService.CreateTab(this.workspaceId, null, true);
this.setActiveTab(tabId);
await this.setActiveTab(tabId, false);
}

async closeTab(tabId: string) {
console.log("closeTab", tabId, this.waveWindowId, this.workspaceId);
const tabView = this.allTabViews.get(tabId);
if (tabView) {
const rtn = await WorkspaceService.CloseTab(this.workspaceId, tabId, true);
this.allTabViews.delete(tabId);
if (rtn?.closewindow) {
this.close();
} else if (rtn?.newactivetabid) {
this.setActiveTab(rtn.newactivetabid);
await this.setActiveTab(rtn.newactivetabid, false);
}
this.allTabViews.delete(tabId);
}
}

Expand Down Expand Up @@ -519,15 +521,15 @@ export async function createBrowserWindow(
console.log("createBrowserWindow", waveWindow.oid, workspace.oid, workspace);
const bwin = new WaveBrowserWindow(waveWindow, fullConfig, opts);
if (workspace.activetabid) {
await bwin.setActiveTab(workspace.activetabid);
await bwin.setActiveTab(workspace.activetabid, false);
}
return bwin;
}

ipcMain.on("set-active-tab", async (event, tabId) => {
const ww = getWaveWindowByWebContentsId(event.sender.id);
console.log("set-active-tab", tabId, ww?.waveWindowId);
await ww?.setActiveTab(tabId);
await ww?.setActiveTab(tabId, true);
});

ipcMain.on("create-tab", async (event, opts) => {
Expand Down
52 changes: 13 additions & 39 deletions pkg/service/workspaceservice/workspaceservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,54 +164,28 @@ func (svc *WorkspaceService) CloseTab(ctx context.Context, workspaceId string, t
if err != nil {
return nil, nil, fmt.Errorf("error getting tab: %w", err)
}
ws, err := wstore.DBMustGet[*waveobj.Workspace](ctx, workspaceId)
if err != nil {
return nil, nil, fmt.Errorf("error getting workspace: %w", err)
}
tabIndex := -1
for i, id := range ws.TabIds {
if id == tabId {
tabIndex = i
break
}
}
go func() {
for _, blockId := range tab.BlockIds {
blockcontroller.StopBlockController(blockId)
}
}()
if err := wcore.DeleteTab(ctx, workspaceId, tabId); err != nil {
newActiveTabId, err := wcore.DeleteTab(ctx, workspaceId, tabId)
if err != nil {
return nil, nil, fmt.Errorf("error closing tab: %w", err)
}
rtn := &CloseTabRtnType{}
if ws.ActiveTabId == tabId && tabIndex != -1 {
if len(ws.TabIds) == 1 {
windowId, err := wstore.DBFindWindowForWorkspaceId(ctx, workspaceId)
if err != nil {
return rtn, nil, fmt.Errorf("unable to find window for workspace id %v: %w", workspaceId, err)
}
rtn.CloseWindow = true
err = wcore.CloseWindow(ctx, windowId, fromElectron)
if err != nil {
return rtn, nil, err
}
} else {
if tabIndex < len(ws.TabIds)-1 {
newActiveTabId := ws.TabIds[tabIndex+1]
err := wcore.SetActiveTab(ctx, ws.OID, newActiveTabId)
if err != nil {
return rtn, nil, err
}
rtn.NewActiveTabId = newActiveTabId
} else {
newActiveTabId := ws.TabIds[tabIndex-1]
err := wcore.SetActiveTab(ctx, ws.OID, newActiveTabId)
if err != nil {
return rtn, nil, err
}
rtn.NewActiveTabId = newActiveTabId
}
if newActiveTabId == "" {
windowId, err := wstore.DBFindWindowForWorkspaceId(ctx, workspaceId)
if err != nil {
return rtn, nil, fmt.Errorf("unable to find window for workspace id %v: %w", workspaceId, err)
}
rtn.CloseWindow = true
err = wcore.CloseWindow(ctx, windowId, fromElectron)
if err != nil {
return rtn, nil, err
}
} else {
rtn.NewActiveTabId = newActiveTabId
}
updates := waveobj.ContextGetUpdatesRtn(ctx)
go func() {
Expand Down
6 changes: 3 additions & 3 deletions pkg/wcore/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func CreateWindow(ctx context.Context, winSize *waveobj.WinSize, workspaceId str
if err != nil {
return nil, fmt.Errorf("error inserting window: %w", err)
}
client, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
client, err := GetClientData(ctx)
if err != nil {
return nil, fmt.Errorf("error getting client: %w", err)
}
Expand All @@ -117,12 +117,12 @@ func CreateWindow(ctx context.Context, winSize *waveobj.WinSize, workspaceId str
if err != nil {
return nil, fmt.Errorf("error updating client: %w", err)
}
return wstore.DBMustGet[*waveobj.Window](ctx, windowId)
return GetWindow(ctx, windowId)
}

func CloseWindow(ctx context.Context, windowId string, fromElectron bool) error {
log.Printf("CloseWindow %s\n", windowId)
window, err := wstore.DBMustGet[*waveobj.Window](ctx, windowId)
window, err := GetWindow(ctx, windowId)
if err == nil {
log.Printf("got window %s\n", windowId)
deleted, err := DeleteWorkspace(ctx, window.WorkspaceId, false)
Expand Down
59 changes: 31 additions & 28 deletions pkg/wcore/workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func DeleteWorkspace(ctx context.Context, workspaceId string, force bool) (bool,
}
for _, tabId := range workspace.TabIds {
log.Printf("deleting tab %s\n", tabId)
err := DeleteTab(ctx, workspaceId, tabId)
_, err := DeleteTab(ctx, workspaceId, tabId)
if err != nil {
return false, fmt.Errorf("error closing tab: %w", err)
}
Expand All @@ -57,9 +57,9 @@ func GetWorkspace(ctx context.Context, wsID string) (*waveobj.Workspace, error)
}

func createTabObj(ctx context.Context, workspaceId string, name string) (*waveobj.Tab, error) {
ws, _ := wstore.DBGet[*waveobj.Workspace](ctx, workspaceId)
if ws == nil {
return nil, fmt.Errorf("workspace not found: %q", workspaceId)
ws, err := GetWorkspace(ctx, workspaceId)
if err != nil {
return nil, fmt.Errorf("workspace %s not found: %w", workspaceId, err)
}
layoutStateId := uuid.NewString()
tab := &waveobj.Tab{
Expand All @@ -81,19 +81,11 @@ func createTabObj(ctx context.Context, workspaceId string, name string) (*waveob
// returns tabid
func CreateTab(ctx context.Context, workspaceId string, tabName string, activateTab bool) (string, error) {
if tabName == "" {
client, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
ws, err := GetWorkspace(ctx, workspaceId)
if err != nil {
return "", fmt.Errorf("error getting client: %w", err)
}
ws, _ := wstore.DBGet[*waveobj.Workspace](ctx, workspaceId)
if ws == nil {
return "", fmt.Errorf("workspace not found: %q", workspaceId)
return "", fmt.Errorf("workspace %s not found: %w", workspaceId, err)
}
tabName = "T" + fmt.Sprint(len(ws.TabIds)+1)
err = wstore.DBUpdate(ctx, client)
if err != nil {
return "", fmt.Errorf("error updating client: %w", err)
}
}
tab, err := createTabObj(ctx, workspaceId, tabName)
if err != nil {
Expand All @@ -109,49 +101,60 @@ func CreateTab(ctx context.Context, workspaceId string, tabName string, activate
return tab.OID, nil
}

// must delete all blocks individually first
// also deletes LayoutState
func DeleteTab(ctx context.Context, workspaceId string, tabId string) error {
// Must delete all blocks individually first.
// Also deletes LayoutState.
// Returns new active tab id, error.
func DeleteTab(ctx context.Context, workspaceId string, tabId string) (string, error) {
ws, _ := wstore.DBGet[*waveobj.Workspace](ctx, workspaceId)
if ws == nil {
return fmt.Errorf("workspace not found: %q", workspaceId)
return "", fmt.Errorf("workspace not found: %q", workspaceId)
}
tab, _ := wstore.DBGet[*waveobj.Tab](ctx, tabId)
if tab == nil {
return fmt.Errorf("tab not found: %q", tabId)
return "", fmt.Errorf("tab not found: %q", tabId)
}

// close blocks (sends events + stops block controllers)
for _, blockId := range tab.BlockIds {
err := DeleteBlock(ctx, blockId)
if err != nil {
return fmt.Errorf("error deleting block %s: %w", blockId, err)
return "", fmt.Errorf("error deleting block %s: %w", blockId, err)
}
}
tabIdx := utilfn.FindStringInSlice(ws.TabIds, tabId)
if tabIdx == -1 {
return nil
return "", nil
}
ws.TabIds = append(ws.TabIds[:tabIdx], ws.TabIds[tabIdx+1:]...)
newActiveTabId := ws.ActiveTabId
if len(ws.TabIds) > 0 {
if ws.ActiveTabId == tabId {
newActiveTabId = ws.TabIds[max(0, min(tabIdx-1, len(ws.TabIds)-1))]
}
} else {
newActiveTabId = ""
}
ws.ActiveTabId = newActiveTabId

wstore.DBUpdate(ctx, ws)
wstore.DBDelete(ctx, waveobj.OType_Tab, tabId)
wstore.DBDelete(ctx, waveobj.OType_LayoutState, tab.LayoutState)
return nil
return newActiveTabId, nil
}

func SetActiveTab(ctx context.Context, workspaceId string, tabId string) error {
workspace, _ := wstore.DBGet[*waveobj.Workspace](ctx, workspaceId)
if workspace == nil {
return fmt.Errorf("workspace not found: %q", workspaceId)
}
if tabId != "" {
workspace, err := GetWorkspace(ctx, workspaceId)
if err != nil {
return fmt.Errorf("workspace %s not found: %w", workspaceId, err)
}
tab, _ := wstore.DBGet[*waveobj.Tab](ctx, tabId)
if tab == nil {
return fmt.Errorf("tab not found: %q", tabId)
}
workspace.ActiveTabId = tabId
wstore.DBUpdate(ctx, workspace)
}
workspace.ActiveTabId = tabId
wstore.DBUpdate(ctx, workspace)
return nil
}

Expand Down