mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
aa77b2c259
![image](https://github.com/user-attachments/assets/a4072368-b204-4eed-bb65-8e3884687f9a) This functions very similarly to VSCode's pinned tab feature. To pin a tab, you can right-click on it and select "Pin tab" from the context menu. Once pinned, a tab will be fixed to the left-most edge of the tab bar, in order of pinning. Pinned tabs can be dragged around like any others. If you drag an unpinned tab into the pinned tabs section (any index less than the highest-index pinned tab), it will be pinned. If you drag a pinned tab out of the pinned tab section, it will be unpinned. Pinned tabs' close button is replaced with a persistent pin button, which can be clicked to unpin them. This adds an extra barrier to accidentally closing a pinned tab. They can still be closed from the context menu.
96 lines
2.7 KiB
Go
96 lines
2.7 KiB
Go
// Copyright 2024, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// wave core application coordinator
|
|
package wcore
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/wavetermdev/waveterm/pkg/waveobj"
|
|
"github.com/wavetermdev/waveterm/pkg/wstore"
|
|
)
|
|
|
|
// the wcore package coordinates actions across the storage layer
|
|
// orchestrating the wave object store, the wave pubsub system, and the wave rpc system
|
|
|
|
// TODO bring Tx infra into wcore
|
|
|
|
const DefaultTimeout = 2 * time.Second
|
|
const DefaultActivateBlockTimeout = 60 * time.Second
|
|
|
|
// Ensures that the initial data is present in the store, creates an initial window if needed
|
|
func EnsureInitialData() error {
|
|
// does not need to run in a transaction since it is called on startup
|
|
ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancelFn()
|
|
client, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
|
|
if err == wstore.ErrNotFound {
|
|
client, err = CreateClient(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating client: %w", err)
|
|
}
|
|
migrateErr := wstore.TryMigrateOldHistory()
|
|
if migrateErr != nil {
|
|
log.Printf("error migrating old history: %v\n", migrateErr)
|
|
}
|
|
}
|
|
if client.TempOID == "" {
|
|
log.Println("client.TempOID is empty")
|
|
client.TempOID = uuid.NewString()
|
|
err = wstore.DBUpdate(ctx, client)
|
|
if err != nil {
|
|
return fmt.Errorf("error updating client: %w", err)
|
|
}
|
|
}
|
|
log.Printf("clientid: %s\n", client.OID)
|
|
if len(client.WindowIds) == 1 {
|
|
log.Println("client has one window")
|
|
CheckAndFixWindow(ctx, client.WindowIds[0])
|
|
return nil
|
|
}
|
|
if len(client.WindowIds) > 0 {
|
|
log.Println("client has windows")
|
|
return nil
|
|
}
|
|
log.Println("client has no windows, creating default workspace")
|
|
defaultWs, err := CreateWorkspace(ctx, "Default workspace", "circle", "green")
|
|
if err != nil {
|
|
return fmt.Errorf("error creating default workspace: %w", err)
|
|
}
|
|
_, err = CreateTab(ctx, defaultWs.OID, "", true, true)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating tab: %w", err)
|
|
}
|
|
_, err = CreateWindow(ctx, nil, defaultWs.OID)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating window: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func CreateClient(ctx context.Context) (*waveobj.Client, error) {
|
|
client := &waveobj.Client{
|
|
OID: uuid.NewString(),
|
|
WindowIds: []string{},
|
|
}
|
|
err := wstore.DBInsert(ctx, client)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error inserting client: %w", err)
|
|
}
|
|
return client, nil
|
|
}
|
|
|
|
func GetClientData(ctx context.Context) (*waveobj.Client, error) {
|
|
clientData, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting client data: %w", err)
|
|
}
|
|
log.Printf("clientData: %v\n", clientData)
|
|
return clientData, nil
|
|
}
|