add scrolltop and selectedline to screen_window

This commit is contained in:
sawka 2022-10-06 18:33:54 -07:00
parent f5b9ea07a1
commit fbe652b932
6 changed files with 134 additions and 19 deletions

View File

@ -50,6 +50,8 @@ CREATE TABLE screen_window (
windowid varchar(36) NOT NULL,
name varchar(50) NOT NULL,
layout json NOT NULL,
selectedline int NOT NULL,
scrolltop int NOT NULL,
PRIMARY KEY (sessionid, screenid, windowid)
);

View File

@ -99,6 +99,8 @@ func init() {
registerCmdFn("remote:install", RemoteInstallCommand)
registerCmdFn("remote:installcancel", RemoteInstallCancelCommand)
registerCmdFn("sw:set", SwSetCommand)
registerCmdFn("window:resize", WindowResizeCommand)
registerCmdFn("line", LineCommand)
@ -200,6 +202,20 @@ func resolvePosInt(arg string, def int) (int, error) {
return ival, nil
}
func resolveNonNegInt(arg string, def int) (int, error) {
if arg == "" {
return def, nil
}
ival, err := strconv.Atoi(arg)
if err != nil {
return 0, err
}
if ival < 0 {
return 0, fmt.Errorf("cannot be negative")
}
return ival, nil
}
func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
ids, err := resolveUiIds(ctx, pk, R_Session|R_Window|R_RemoteConnected)
if err != nil {
@ -409,6 +425,33 @@ func ScreenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstor
return update, nil
}
func SwSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen|R_Window)
if err != nil {
return nil, fmt.Errorf("/sw:set cannot resolve current screen-window: %w", err)
}
var setNonST bool // scrolltop does not receive an update
updateMap := make(map[string]interface{})
if pk.Kwargs["scrolltop"] != "" {
stVal, err := resolveNonNegInt(pk.Kwargs["scrolltop"], 0)
if err != nil {
return nil, fmt.Errorf("/sw:set invalid scrolltop argument: %v", err)
}
updateMap[sstore.SWField_ScrollTop] = stVal
}
if len(updateMap) == 0 {
return nil, fmt.Errorf("/sw:set no updates, can set %s", formatStrs([]string{"line", "scrolltop"}, "or", false))
}
sw, err := sstore.UpdateScreenWindow(ctx, ids.SessionId, ids.ScreenId, ids.WindowId, updateMap)
if err != nil {
return nil, fmt.Errorf("/sw:set failed to update: %v", err)
}
if !setNonST {
return nil, nil
}
return sstore.ModelUpdate{ScreenWindow: sw}, nil
}
func UnSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
ids, err := resolveUiIds(ctx, pk, R_Session|R_Window|R_RemoteConnected)
if err != nil {

View File

@ -143,6 +143,24 @@ func resolveUiIds(ctx context.Context, pk *scpacket.FeCommandPacketType, rtype i
rtn.ScreenId = uictx.ScreenId
rtn.WindowId = uictx.WindowId
}
if pk.Kwargs["session"] != "" {
sessionId, err := resolveSessionArg(pk.Kwargs["session"])
if err != nil {
return rtn, err
}
if sessionId != "" {
rtn.SessionId = sessionId
}
}
if pk.Kwargs["screen"] != "" {
screenId, err := resolveScreenArg(rtn.SessionId, pk.Kwargs["screen"])
if err != nil {
return rtn, err
}
if screenId != "" {
rtn.ScreenId = screenId
}
}
if pk.Kwargs["window"] != "" {
windowId, err := resolveWindowArg(rtn.SessionId, rtn.ScreenId, pk.Kwargs["window"])
if err != nil {
@ -274,6 +292,26 @@ func resolveWindowArg(sessionId string, screenId string, windowArg string) (stri
return windowArg, nil
}
func resolveSessionArg(sessionArg string) (string, error) {
if sessionArg == "" {
return "", nil
}
if _, err := uuid.Parse(sessionArg); err != nil {
return "", fmt.Errorf("invalid session arg specified (must be sessionid) '%s'", sessionArg)
}
return sessionArg, nil
}
func resolveScreenArg(sessionId string, screenArg string) (string, error) {
if screenArg == "" {
return "", nil
}
if _, err := uuid.Parse(screenArg); err != nil {
return "", fmt.Errorf("invalid screen arg specified (must be sessionid) '%s'", screenArg)
}
return screenArg, nil
}
func resolveScreenId(ctx context.Context, pk *scpacket.FeCommandPacketType, sessionId string) (string, error) {
screenArg := pk.Kwargs["screen"]
if screenArg == "" {

View File

@ -498,8 +498,8 @@ func InsertScreen(ctx context.Context, sessionId string, origScreenName string,
query = `INSERT INTO screen (sessionid, screenid, name, activewindowid, screenidx, screenopts, ownerid, sharemode) VALUES (?, ?, ?, ?, ?, ?, '', 'local')`
tx.ExecWrap(query, sessionId, newScreenId, screenName, newWindowId, maxScreenIdx+1, ScreenOptsType{})
layout := LayoutType{Type: LayoutFull}
query = `INSERT INTO screen_window (sessionid, screenid, windowid, name, layout) VALUES (?, ?, ?, ?, ?)`
tx.ExecWrap(query, sessionId, newScreenId, newWindowId, DefaultScreenWindowName, layout)
query = `INSERT INTO screen_window (sessionid, screenid, windowid, name, layout, selectedline, scrolltop) VALUES (?, ?, ?, ?, ?, ?, ?)`
tx.ExecWrap(query, sessionId, newScreenId, newWindowId, DefaultScreenWindowName, layout, 0, 0)
if activate {
query = `UPDATE session SET activescreenid = ? WHERE sessionid = ?`
tx.ExecWrap(query, newScreenId, sessionId)
@ -619,7 +619,6 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error {
if line.LineNum != 0 {
return fmt.Errorf("line should not hage linenum set")
}
cmd.OrigTermOpts = cmd.TermOpts
return WithTx(ctx, func(tx *TxWrap) error {
query := `SELECT windowid FROM window WHERE sessionid = ? AND windowid = ?`
if !tx.Exists(query, line.SessionId, line.WindowId) {
@ -634,6 +633,7 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error {
query = `UPDATE window SET nextlinenum = ? WHERE sessionid = ? AND windowid = ?`
tx.ExecWrap(query, nextLineNum+1, line.SessionId, line.WindowId)
if cmd != nil {
cmd.OrigTermOpts = cmd.TermOpts
cmdMap := cmd.ToMap()
query = `
INSERT INTO cmd ( sessionid, cmdid, remoteownerid, remoteid, remotename, cmdstr, remotestate, termopts, origtermopts, status, startpk, donepk, runout, usedrows)
@ -1103,3 +1103,32 @@ func UpdateRemote(ctx context.Context, remoteId string, editMap map[string]inter
}
return rtn, nil
}
const (
SWField_ScrollTop = "scrolltop" // int
)
func UpdateScreenWindow(ctx context.Context, sessionId string, screenId string, windowId string, editMap map[string]interface{}) (*ScreenWindowType, error) {
var rtn *ScreenWindowType
txErr := WithTx(ctx, func(tx *TxWrap) error {
query := `SELECT sessionid FROM screen_window WHERE sessionid = ? AND screenid = ? AND windowid = ?`
if !tx.Exists(query, sessionId, screenId, windowId) {
return fmt.Errorf("screen-window not found")
}
if stVal, found := editMap[SWField_ScrollTop]; found {
query = `UPDATE screen_window SET scrolltop = ? WHERE sessionid = ? AND screenid = ? AND windowid = ?`
tx.ExecWrap(query, stVal, sessionId, screenId, windowId)
}
var sw ScreenWindowType
query = `SELECT * FROM screen_window WHERE sessionid = ? AND screenid = ? AND windowid = ?`
found := tx.GetWrap(&sw, query, sessionId, screenId, windowId)
if found {
rtn = &sw
}
return nil
})
if txErr != nil {
return nil, txErr
}
return rtn, nil
}

View File

@ -376,11 +376,13 @@ func (l LayoutType) Value() (driver.Value, error) {
}
type ScreenWindowType struct {
SessionId string `json:"sessionid"`
ScreenId string `json:"screenid"`
WindowId string `json:"windowid"`
Name string `json:"name"`
Layout LayoutType `json:"layout"`
SessionId string `json:"sessionid"`
ScreenId string `json:"screenid"`
WindowId string `json:"windowid"`
Name string `json:"name"`
Layout LayoutType `json:"layout"`
SelectedLine int `json:"selectedline"`
ScrollTop int `json:"scrolltop"`
// only for updates
Remove bool `json:"remove,omitempty"`

View File

@ -29,17 +29,18 @@ func (PtyDataUpdate) UpdateType() string {
}
type ModelUpdate struct {
Sessions []*SessionType `json:"sessions,omitempty"`
ActiveSessionId string `json:"activesessionid,omitempty"`
Window *WindowType `json:"window,omitempty"`
Line *LineType `json:"line,omitempty"`
Cmd *CmdType `json:"cmd,omitempty"`
CmdLine *CmdLineType `json:"cmdline,omitempty"`
Info *InfoMsgType `json:"info,omitempty"`
Remotes []interface{} `json:"remotes,omitempty"` // []*remote.RemoteState
History *HistoryInfoType `json:"history,omitempty"`
Interactive bool `json:"interactive"`
Connect bool `json:"connect,omitempty"`
Sessions []*SessionType `json:"sessions,omitempty"`
ActiveSessionId string `json:"activesessionid,omitempty"`
Window *WindowType `json:"window,omitempty"`
ScreenWindow *ScreenWindowType `json:"screenwindow,omitempty"`
Line *LineType `json:"line,omitempty"`
Cmd *CmdType `json:"cmd,omitempty"`
CmdLine *CmdLineType `json:"cmdline,omitempty"`
Info *InfoMsgType `json:"info,omitempty"`
Remotes []interface{} `json:"remotes,omitempty"` // []*remote.RemoteState
History *HistoryInfoType `json:"history,omitempty"`
Interactive bool `json:"interactive"`
Connect bool `json:"connect,omitempty"`
}
func (ModelUpdate) UpdateType() string {