waveterm/wavesrv/pkg/scbus/modelupdate.go
Mike Sawka 3c3eec73aa
reinit updates (#500)
* working on re-init when you create a tab.  some refactoring of existing reinit to make the messaging clearer.  auto-connect, etc.

* working to remove the 'default' shell states out of MShellProc.  each tab should have its own state that gets set on open.

* refactor newtab settings into individual components (and move to a new file)

* more refactoring of tab settings -- use same control in settings and newtab

* have screensettings use the same newtab settings components

* use same conn dropdown, fix classes, update some of the confirm messages to be less confusing (replace screen with tab)

* force a cr on a new tab to initialize state in a new line.  poc right now, need to add to new workspace workflow as well

* small fixups

* remove nohist from GetRawStr, make const

* update hover behavior for tabs

* fix interaction between change remote dropdown, cmdinput, error handling, and selecting a remote

* only switch screen remote if the activemainview is session (new remote flow).  don't switch it if we're on the connections page which is confusing.  also make it interactive

* fix wording on tos modal

* allow empty workspaces. also allow the last workspace to be deleted.  (prep for new startup sequence where we initialize the first session after tos modal)

* add some dead code that might come in use later (when we change how we show connection in cmdinput)

* working a cople different angles.  new settings tab-pulldown (likely orphaned).  and then allowing null activeScreen and null activeSession in workspaceview (show appropriate messages, and give buttons to create new tabs/workspaces).  prep for new startup flow

* don't call initActiveShells anymore.  also call ensureWorkspace() on TOS close

* trying to use new pulldown screen settings

* experiment with an escape keybinding

* working on tab settings close triggers

* close tab settings on tab switch

* small updates to tos popup, reorder, update button text/size, small wording updates

* when deleting a screen, send SIGHUP to all running commands

* not sure how this happened, lineid should not be passed to setLineFocus

* remove context timeouts for ReInit (it is now interactive, so it gets canceled like a normal command -- via ^C, and should not timeout on its own)

* deal with screen/session tombstones updates (ignore to quite warning)

* remove defaultfestate from remote

* fix issue with removing default ris

* remove dead code

* open the settings pulldown for new screens

* update prompt to show when the shell is still initializing (or if it failed)

* switch buttons to use wave button class, update messages, and add warning for no shell state

* all an override of rptr for dyncmds.  needed for the 'connect' command (we need to set the rptr to the *new* connection rather than the old one)

* remove old commented out code
2024-03-27 00:22:57 -07:00

141 lines
3.1 KiB
Go

// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package scbus
import (
"encoding/json"
"fmt"
"reflect"
"github.com/wavetermdev/waveterm/waveshell/pkg/packet"
)
const ModelUpdateStr = "model"
// A channel for sending model updates to the client
type ModelUpdateChannel[J any] struct {
ScreenId string
ClientId string
ch chan J
}
func (uch *ModelUpdateChannel[J]) GetChannel() chan J {
return uch.ch
}
func (uch *ModelUpdateChannel[J]) SetChannel(ch chan J) {
uch.ch = ch
}
// Match the screenId to the channel
func (sch *ModelUpdateChannel[J]) Match(screenId string) bool {
if screenId == "" {
return true
}
return screenId == sch.ScreenId
}
// An interface for all model updates
type ModelUpdateItem interface {
// The key to use when marshalling to JSON and interpreting in the client
GetType() string
}
// An inner data type for the ModelUpdatePacketType. Stores a collection of model updates to be sent to the client.
type ModelUpdate []ModelUpdateItem
func (mu *ModelUpdate) IsEmpty() bool {
if mu == nil {
return true
}
muArr := []ModelUpdateItem(*mu)
return len(muArr) == 0
}
func (mu *ModelUpdate) MarshalJSON() ([]byte, error) {
rtn := make([]map[string]any, 0)
for _, u := range *mu {
m := make(map[string]any)
m[(u).GetType()] = u
rtn = append(rtn, m)
}
return json.Marshal(rtn)
}
// An UpdatePacket for sending model updates to the client
type ModelUpdatePacketType struct {
Type string `json:"type"`
Data *ModelUpdate `json:"data"`
}
func (*ModelUpdatePacketType) GetType() string {
return ModelUpdateStr
}
func (upk *ModelUpdatePacketType) IsEmpty() bool {
if upk == nil {
return true
}
return upk.Data.IsEmpty()
}
// Clean the ClientData in an update, if present
func (upk *ModelUpdatePacketType) Clean() {
if upk.IsEmpty() {
return
}
for _, item := range *(upk.Data) {
if i, ok := (item).(CleanableUpdateItem); ok {
i.Clean()
}
}
}
// Add a collection of model updates to the update
func (upk *ModelUpdatePacketType) AddUpdate(items ...ModelUpdateItem) {
*(upk.Data) = append(*(upk.Data), items...)
}
// adds the items from p2 to the update (p2 must be ModelUpdatePacketType)
func (upk *ModelUpdatePacketType) Merge(p2Arg UpdatePacket) error {
p2, ok := p2Arg.(*ModelUpdatePacketType)
if !ok {
return fmt.Errorf("cannot merge ModelUpdatePacketType with %T", p2Arg)
}
*(upk.Data) = append(*(upk.Data), *(p2.Data)...)
return nil
}
// Create a new model update packet
func MakeUpdatePacket() *ModelUpdatePacketType {
return &ModelUpdatePacketType{
Type: ModelUpdateStr,
Data: &ModelUpdate{},
}
}
// Returns the items in the update that are of type I
func GetUpdateItems[I ModelUpdateItem](upk *ModelUpdatePacketType) []*I {
if upk.IsEmpty() {
return nil
}
ret := make([]*I, 0)
for _, item := range *(upk.Data) {
if i, ok := (item).(I); ok {
ret = append(ret, &i)
}
}
return ret
}
// An interface for model updates that can be cleaned
type CleanableUpdateItem interface {
Clean()
}
func init() {
// Register the model update packet type
packet.RegisterPacketType(ModelUpdateStr, reflect.TypeOf(ModelUpdatePacketType{}))
}