mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
implement cmd:i, hook up telemetry switch, fix some settings types
This commit is contained in:
parent
e3b7ab73c0
commit
70ef76be62
@ -27,6 +27,7 @@ func GenerateWshClient() {
|
|||||||
"github.com/wavetermdev/thenextwave/pkg/wshutil",
|
"github.com/wavetermdev/thenextwave/pkg/wshutil",
|
||||||
"github.com/wavetermdev/thenextwave/pkg/wshrpc",
|
"github.com/wavetermdev/thenextwave/pkg/wshrpc",
|
||||||
"github.com/wavetermdev/thenextwave/pkg/waveobj",
|
"github.com/wavetermdev/thenextwave/pkg/waveobj",
|
||||||
|
"github.com/wavetermdev/thenextwave/pkg/wconfig",
|
||||||
})
|
})
|
||||||
wshDeclMap := wshrpc.GenerateWshCommandDeclMap()
|
wshDeclMap := wshrpc.GenerateWshCommandDeclMap()
|
||||||
for _, key := range utilfn.GetOrderedMapKeys(wshDeclMap) {
|
for _, key := range utilfn.GetOrderedMapKeys(wshDeclMap) {
|
||||||
|
@ -5,6 +5,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/wavetermdev/thenextwave/pkg/wconfig"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/wshrpc"
|
"github.com/wavetermdev/thenextwave/pkg/wshrpc"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/wshrpc/wshclient"
|
"github.com/wavetermdev/thenextwave/pkg/wshrpc/wshclient"
|
||||||
)
|
)
|
||||||
@ -28,7 +29,8 @@ func setConfigRun(cmd *cobra.Command, args []string) {
|
|||||||
WriteStderr("[error] %v\n", err)
|
WriteStderr("[error] %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = wshclient.SetConfigCommand(RpcClient, meta, &wshrpc.RpcOpts{Timeout: 2000})
|
commandData := wconfig.MetaSettingsType{MetaMapType: meta}
|
||||||
|
err = wshclient.SetConfigCommand(RpcClient, commandData, &wshrpc.RpcOpts{Timeout: 2000})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteStderr("[error] setting config: %v\n", err)
|
WriteStderr("[error] setting config: %v\n", err)
|
||||||
return
|
return
|
||||||
|
@ -7,6 +7,7 @@ import { Toggle } from "@/app/element/toggle";
|
|||||||
import * as services from "@/store/services";
|
import * as services from "@/store/services";
|
||||||
import { FlexiModal } from "./modal";
|
import { FlexiModal } from "./modal";
|
||||||
|
|
||||||
|
import { WshServer } from "@/app/store/wshserver";
|
||||||
import "./tos.less";
|
import "./tos.less";
|
||||||
|
|
||||||
const TosModal = () => {
|
const TosModal = () => {
|
||||||
@ -14,6 +15,10 @@ const TosModal = () => {
|
|||||||
services.ClientService.AgreeTos();
|
services.ClientService.AgreeTos();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function setTelemetry(value: boolean) {
|
||||||
|
WshServer.SetConfigCommand({ "telemetry:enabled": value });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlexiModal className="tos-modal">
|
<FlexiModal className="tos-modal">
|
||||||
<div className="modal-inner">
|
<div className="modal-inner">
|
||||||
@ -76,7 +81,7 @@ const TosModal = () => {
|
|||||||
</a>
|
</a>
|
||||||
to help us understand how people are using Wave.
|
to help us understand how people are using Wave.
|
||||||
</div>
|
</div>
|
||||||
<Toggle checked={true} onChange={() => {}} label="Telemetry enabled" />
|
<Toggle checked={true} onChange={setTelemetry} label="Telemetry enabled" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright 2024, Command Line Inc.
|
// Copyright 2024, Command Line Inc.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { atoms, createBlock, getApi, getViewModel, globalStore, WOS } from "@/app/store/global";
|
import { atoms, createBlock, getApi, getViewModel, globalStore, refocusNode, WOS } from "@/app/store/global";
|
||||||
import * as services from "@/app/store/services";
|
import * as services from "@/app/store/services";
|
||||||
import {
|
import {
|
||||||
deleteLayoutModelForTab,
|
deleteLayoutModelForTab,
|
||||||
@ -112,6 +112,21 @@ function switchTab(offset: number) {
|
|||||||
services.ObjectService.SetActiveTab(newActiveTabId);
|
services.ObjectService.SetActiveTab(newActiveTabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCmdI() {
|
||||||
|
const layoutModel = getLayoutModelForActiveTab();
|
||||||
|
const focusedNode = globalStore.get(layoutModel.focusedNode);
|
||||||
|
if (focusedNode == null) {
|
||||||
|
// focus a node
|
||||||
|
layoutModel.focusFirstNode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const blockId = focusedNode?.data?.blockId;
|
||||||
|
if (blockId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refocusNode(blockId);
|
||||||
|
}
|
||||||
|
|
||||||
async function handleCmdN() {
|
async function handleCmdN() {
|
||||||
const termBlockDef: BlockDef = {
|
const termBlockDef: BlockDef = {
|
||||||
meta: {
|
meta: {
|
||||||
@ -198,7 +213,7 @@ function registerGlobalKeys() {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
globalKeyMap.set("Cmd:i", () => {
|
globalKeyMap.set("Cmd:i", () => {
|
||||||
// TODO
|
handleCmdI();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
globalKeyMap.set("Cmd:t", () => {
|
globalKeyMap.set("Cmd:t", () => {
|
||||||
|
@ -128,7 +128,7 @@ class WshServerType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// command "setconfig" [call]
|
// command "setconfig" [call]
|
||||||
SetConfigCommand(data: MetaType, opts?: RpcOpts): Promise<void> {
|
SetConfigCommand(data: SettingsType, opts?: RpcOpts): Promise<void> {
|
||||||
return WOS.wshServerRpcHelper_call("setconfig", data, opts);
|
return WOS.wshServerRpcHelper_call("setconfig", data, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,21 +716,6 @@ function CodeEditPreview({ parentRef, model }: SpecializedViewProps) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (false) {
|
|
||||||
// bind Cmd:e
|
|
||||||
editor.addCommand(simpleMod | monaco.KeyCode.KeyE, () => {
|
|
||||||
model.setEditMode(false);
|
|
||||||
});
|
|
||||||
// bind Cmd:s
|
|
||||||
editor.addCommand(simpleMod | monaco.KeyCode.KeyS, () => {
|
|
||||||
model.handleFileSave();
|
|
||||||
});
|
|
||||||
// bind Cmd:o
|
|
||||||
editor.addCommand(simpleMod | monaco.KeyCode.KeyO, () => {
|
|
||||||
model.updateOpenFileModalAndError(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const isFocused = globalStore.get(model.nodeModel.isFocused);
|
const isFocused = globalStore.get(model.nodeModel.isFocused);
|
||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
editor.focus();
|
editor.focus();
|
||||||
|
@ -10,6 +10,7 @@ import * as jotai from "jotai";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { CenteredDiv } from "../element/quickelems";
|
import { CenteredDiv } from "../element/quickelems";
|
||||||
|
|
||||||
|
import { ErrorBoundary } from "@/app/element/errorboundary";
|
||||||
import "./workspace.less";
|
import "./workspace.less";
|
||||||
|
|
||||||
const iconRegex = /^[a-z0-9-]+$/;
|
const iconRegex = /^[a-z0-9-]+$/;
|
||||||
@ -107,6 +108,7 @@ const WorkspaceElem = React.memo(() => {
|
|||||||
<div className="workspace">
|
<div className="workspace">
|
||||||
<TabBar key={ws.oid} workspace={ws} />
|
<TabBar key={ws.oid} workspace={ws} />
|
||||||
<div className="workspace-tabcontent">
|
<div className="workspace-tabcontent">
|
||||||
|
<ErrorBoundary>
|
||||||
{activeTabId == "" ? (
|
{activeTabId == "" ? (
|
||||||
<CenteredDiv>No Active Tab</CenteredDiv>
|
<CenteredDiv>No Active Tab</CenteredDiv>
|
||||||
) : (
|
) : (
|
||||||
@ -116,6 +118,7 @@ const WorkspaceElem = React.memo(() => {
|
|||||||
<ModalsRenderer />
|
<ModalsRenderer />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
</ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -874,6 +874,11 @@ export class LayoutModel {
|
|||||||
*/
|
*/
|
||||||
focusNode(nodeId: string) {
|
focusNode(nodeId: string) {
|
||||||
if (this.focusedNodeId === nodeId) return;
|
if (this.focusedNodeId === nodeId) return;
|
||||||
|
const layoutNode = findNode(this.treeState?.rootNode, nodeId);
|
||||||
|
if (!layoutNode) {
|
||||||
|
console.error("unable to focus node, cannot find it in tree", nodeId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const action: LayoutTreeFocusNodeAction = {
|
const action: LayoutTreeFocusNodeAction = {
|
||||||
type: LayoutTreeActionType.FocusNode,
|
type: LayoutTreeActionType.FocusNode,
|
||||||
nodeId: nodeId,
|
nodeId: nodeId,
|
||||||
@ -882,6 +887,13 @@ export class LayoutModel {
|
|||||||
this.treeReducer(action);
|
this.treeReducer(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
focusFirstNode() {
|
||||||
|
const leafOrder = this.getter(this.leafOrder);
|
||||||
|
if (leafOrder.length > 0) {
|
||||||
|
this.focusNode(leafOrder[0].nodeid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle magnification of a given node.
|
* Toggle magnification of a given node.
|
||||||
* @param nodeId The id of the node that is being magnified.
|
* @param nodeId The id of the node that is being magnified.
|
||||||
|
@ -56,6 +56,7 @@ var contextRType = reflect.TypeOf((*context.Context)(nil)).Elem()
|
|||||||
var errorRType = reflect.TypeOf((*error)(nil)).Elem()
|
var errorRType = reflect.TypeOf((*error)(nil)).Elem()
|
||||||
var anyRType = reflect.TypeOf((*interface{})(nil)).Elem()
|
var anyRType = reflect.TypeOf((*interface{})(nil)).Elem()
|
||||||
var metaRType = reflect.TypeOf((*waveobj.MetaMapType)(nil)).Elem()
|
var metaRType = reflect.TypeOf((*waveobj.MetaMapType)(nil)).Elem()
|
||||||
|
var metaSettingsType = reflect.TypeOf((*wconfig.MetaSettingsType)(nil)).Elem()
|
||||||
var uiContextRType = reflect.TypeOf((*waveobj.UIContext)(nil)).Elem()
|
var uiContextRType = reflect.TypeOf((*waveobj.UIContext)(nil)).Elem()
|
||||||
var waveObjRType = reflect.TypeOf((*waveobj.WaveObj)(nil)).Elem()
|
var waveObjRType = reflect.TypeOf((*waveobj.WaveObj)(nil)).Elem()
|
||||||
var updatesRtnRType = reflect.TypeOf(waveobj.UpdatesRtnType{})
|
var updatesRtnRType = reflect.TypeOf(waveobj.UpdatesRtnType{})
|
||||||
@ -163,6 +164,7 @@ var tsRenameMap = map[string]string{
|
|||||||
"Window": "WaveWindow",
|
"Window": "WaveWindow",
|
||||||
"Elem": "VDomElem",
|
"Elem": "VDomElem",
|
||||||
"MetaTSType": "MetaType",
|
"MetaTSType": "MetaType",
|
||||||
|
"MetaSettingsType": "SettingsType",
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateTSTypeInternal(rtype reflect.Type, tsTypesMap map[reflect.Type]string) (string, []reflect.Type) {
|
func generateTSTypeInternal(rtype reflect.Type, tsTypesMap map[reflect.Type]string) (string, []reflect.Type) {
|
||||||
@ -286,6 +288,9 @@ func GenerateTSType(rtype reflect.Type, tsTypesMap map[reflect.Type]string) {
|
|||||||
tsTypesMap[rtype] = GenerateWaveObjTSType()
|
tsTypesMap[rtype] = GenerateWaveObjTSType()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if rtype == metaSettingsType {
|
||||||
|
return
|
||||||
|
}
|
||||||
if rtype.Kind() != reflect.Struct {
|
if rtype.Kind() != reflect.Struct {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -20,17 +20,34 @@ import (
|
|||||||
|
|
||||||
const SettingsFile = "settings.json"
|
const SettingsFile = "settings.json"
|
||||||
|
|
||||||
|
type MetaSettingsType struct {
|
||||||
|
waveobj.MetaMapType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MetaSettingsType) UnmarshalJSON(data []byte) error {
|
||||||
|
var metaMap waveobj.MetaMapType
|
||||||
|
if err := json.Unmarshal(data, &metaMap); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = MetaSettingsType{MetaMapType: metaMap}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MetaSettingsType) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(m.MetaMapType)
|
||||||
|
}
|
||||||
|
|
||||||
type SettingsType struct {
|
type SettingsType struct {
|
||||||
AiClear bool `json:"ai:*,omitempty"`
|
AiClear bool `json:"ai:*,omitempty"`
|
||||||
AiBaseURL string `json:"ai:baseurl,omitempty"`
|
AiBaseURL string `json:"ai:baseurl,omitempty"`
|
||||||
AiApiToken string `json:"ai:apitoken,omitempty"`
|
AiApiToken string `json:"ai:apitoken,omitempty"`
|
||||||
AiName string `json:"ai:name,omitempty"`
|
AiName string `json:"ai:name,omitempty"`
|
||||||
AiModel string `json:"ai:model,omitempty"`
|
AiModel string `json:"ai:model,omitempty"`
|
||||||
AiMaxTokens int `json:"ai:maxtokens,omitempty"`
|
AiMaxTokens float64 `json:"ai:maxtokens,omitempty"`
|
||||||
AiTimeoutMs int `json:"ai:timeoutms,omitempty"`
|
AiTimeoutMs float64 `json:"ai:timeoutms,omitempty"`
|
||||||
|
|
||||||
TermClear bool `json:"term:*,omitempty"`
|
TermClear bool `json:"term:*,omitempty"`
|
||||||
TermFontSize int `json:"term:fontsize,omitempty"`
|
TermFontSize float64 `json:"term:fontsize,omitempty"`
|
||||||
TermFontFamily string `json:"term:fontfamily,omitempty"`
|
TermFontFamily string `json:"term:fontfamily,omitempty"`
|
||||||
TermDisableWebGl bool `json:"term:disablewebgl,omitempty"`
|
TermDisableWebGl bool `json:"term:disablewebgl,omitempty"`
|
||||||
|
|
||||||
@ -42,7 +59,7 @@ type SettingsType struct {
|
|||||||
|
|
||||||
AutoUpdateClear bool `json:"autoupdate:*,omitempty"`
|
AutoUpdateClear bool `json:"autoupdate:*,omitempty"`
|
||||||
AutoUpdateEnabled bool `json:"autoupdate:enabled,omitempty"`
|
AutoUpdateEnabled bool `json:"autoupdate:enabled,omitempty"`
|
||||||
AutoUpdateIntervalMs int `json:"autoupdate:intervalms,omitempty"`
|
AutoUpdateIntervalMs float64 `json:"autoupdate:intervalms,omitempty"`
|
||||||
AutoUpdateInstallOnQuit bool `json:"autoupdate:installonquit,omitempty"`
|
AutoUpdateInstallOnQuit bool `json:"autoupdate:installonquit,omitempty"`
|
||||||
|
|
||||||
WidgetClear bool `json:"widget:*,omitempty"`
|
WidgetClear bool `json:"widget:*,omitempty"`
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/wavetermdev/thenextwave/pkg/wshutil"
|
"github.com/wavetermdev/thenextwave/pkg/wshutil"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/wshrpc"
|
"github.com/wavetermdev/thenextwave/pkg/wshrpc"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/waveobj"
|
"github.com/wavetermdev/thenextwave/pkg/waveobj"
|
||||||
|
"github.com/wavetermdev/thenextwave/pkg/wconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
// command "announce", wshserver.AnnounceCommand
|
// command "announce", wshserver.AnnounceCommand
|
||||||
@ -154,7 +155,7 @@ func ResolveIdsCommand(w *wshutil.WshRpc, data wshrpc.CommandResolveIdsData, opt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// command "setconfig", wshserver.SetConfigCommand
|
// command "setconfig", wshserver.SetConfigCommand
|
||||||
func SetConfigCommand(w *wshutil.WshRpc, data waveobj.MetaMapType, opts *wshrpc.RpcOpts) error {
|
func SetConfigCommand(w *wshutil.WshRpc, data wconfig.MetaSettingsType, opts *wshrpc.RpcOpts) error {
|
||||||
_, err := sendRpcRequestCallHelper[any](w, "setconfig", data, opts)
|
_, err := sendRpcRequestCallHelper[any](w, "setconfig", data, opts)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/wavetermdev/thenextwave/pkg/ijson"
|
"github.com/wavetermdev/thenextwave/pkg/ijson"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/util/utilfn"
|
"github.com/wavetermdev/thenextwave/pkg/util/utilfn"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/waveobj"
|
"github.com/wavetermdev/thenextwave/pkg/waveobj"
|
||||||
|
"github.com/wavetermdev/thenextwave/pkg/wconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
const LocalConnName = "local"
|
const LocalConnName = "local"
|
||||||
@ -94,7 +95,7 @@ type WshRpcInterface interface {
|
|||||||
StreamWaveAiCommand(ctx context.Context, request OpenAiStreamRequest) chan RespOrErrorUnion[OpenAIPacketType]
|
StreamWaveAiCommand(ctx context.Context, request OpenAiStreamRequest) chan RespOrErrorUnion[OpenAIPacketType]
|
||||||
StreamCpuDataCommand(ctx context.Context, request CpuDataRequest) chan RespOrErrorUnion[TimeSeriesData]
|
StreamCpuDataCommand(ctx context.Context, request CpuDataRequest) chan RespOrErrorUnion[TimeSeriesData]
|
||||||
TestCommand(ctx context.Context, data string) error
|
TestCommand(ctx context.Context, data string) error
|
||||||
SetConfigCommand(ctx context.Context, data waveobj.MetaMapType) error
|
SetConfigCommand(ctx context.Context, data wconfig.MetaSettingsType) error
|
||||||
|
|
||||||
// eventrecv is special, it's handled internally by WshRpc with EventListener
|
// eventrecv is special, it's handled internally by WshRpc with EventListener
|
||||||
EventRecvCommand(ctx context.Context, data WaveEvent) error
|
EventRecvCommand(ctx context.Context, data WaveEvent) error
|
||||||
|
@ -463,6 +463,7 @@ func (ws *WshServer) EventReadHistoryCommand(ctx context.Context, data wshrpc.Co
|
|||||||
return events, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WshServer) SetConfigCommand(ctx context.Context, data waveobj.MetaMapType) error {
|
func (ws *WshServer) SetConfigCommand(ctx context.Context, data wconfig.MetaSettingsType) error {
|
||||||
return wconfig.SetBaseConfigValue(data)
|
log.Printf("SETCONFIG: %v\n", data)
|
||||||
|
return wconfig.SetBaseConfigValue(data.MetaMapType)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user