mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-21 21:32:13 +01:00
tos page 2 -- quick tips (#387)
This commit is contained in:
parent
87d3f8d88d
commit
46eb164778
83
frontend/app/element/quicktips.less
Normal file
83
frontend/app/element/quicktips.less
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
.tips-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
.tips-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
gap: 5px;
|
||||
|
||||
.tip-section-header {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tip {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
code {
|
||||
padding: 0.1em 0.4em;
|
||||
background-color: var(--highlight-bg-color);
|
||||
}
|
||||
|
||||
.keybinding-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.keybinding {
|
||||
display: inline-block;
|
||||
padding: 0.1em 0.4em;
|
||||
margin: 0 0.1em;
|
||||
font: var(--fixed-font);
|
||||
font-size: 0.85em;
|
||||
color: var(--keybinding-color);
|
||||
background-color: var(--keybinding-bg-color);
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--keybinding-border-color);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.icon-wrap {
|
||||
background-color: var(--highlight-bg-color);
|
||||
padding: 2px;
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 12px;
|
||||
border-radius: 2px;
|
||||
margin-right: 5px;
|
||||
|
||||
svg {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
left: 1px;
|
||||
height: 13px;
|
||||
#arrow1,
|
||||
#arrow2 {
|
||||
fill: var(--main-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
152
frontend/app/element/quicktips.tsx
Normal file
152
frontend/app/element/quicktips.tsx
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { MagnifyIcon } from "@/app/element/magnify";
|
||||
import { PLATFORM } from "@/app/store/global";
|
||||
import "./quicktips.less";
|
||||
|
||||
const KeyBinding = ({ keyDecl }: { keyDecl: string }) => {
|
||||
const parts = keyDecl.split(":");
|
||||
const elems: React.ReactNode[] = [];
|
||||
for (let part of parts) {
|
||||
if (part === "Cmd") {
|
||||
if (PLATFORM === "darwin") {
|
||||
elems.push(
|
||||
<div key="cmd" className="keybinding">
|
||||
⌘ Cmd
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
elems.push(
|
||||
<div key="alt" className="keybinding">
|
||||
Alt
|
||||
</div>
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (part == "Ctrl") {
|
||||
elems.push(
|
||||
<div key="ctrl" className="keybinding">
|
||||
^ Ctrl
|
||||
</div>
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (part == "Shift") {
|
||||
elems.push(
|
||||
<div key="shift" className="keybinding">
|
||||
⇧ Shift
|
||||
</div>
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (part == "Arrows") {
|
||||
elems.push(
|
||||
<div key="arrows1" className="keybinding">
|
||||
←
|
||||
</div>
|
||||
);
|
||||
elems.push(
|
||||
<div key="arrows2" className="keybinding">
|
||||
→
|
||||
</div>
|
||||
);
|
||||
elems.push(
|
||||
<div key="arrows3" className="keybinding">
|
||||
↑
|
||||
</div>
|
||||
);
|
||||
elems.push(
|
||||
<div key="arrows4" className="keybinding">
|
||||
↓
|
||||
</div>
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (part == "Digit") {
|
||||
elems.push(
|
||||
<div key="digit" className="keybinding">
|
||||
Number (1-9)
|
||||
</div>
|
||||
);
|
||||
continue;
|
||||
}
|
||||
elems.push(
|
||||
<div key={part} className="keybinding">
|
||||
{part.toUpperCase()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <div className="keybinding-group">{elems}</div>;
|
||||
};
|
||||
|
||||
const QuickTips = () => {
|
||||
return (
|
||||
<div className="tips-wrapper">
|
||||
<div className="tips-section">
|
||||
<div className="tip-section-header">Header Icons</div>
|
||||
<div className="tip">
|
||||
<div className="icon-wrap">
|
||||
<i className="fa-solid fa-sharp fa-laptop fa-fw" />
|
||||
</div>
|
||||
Connect to a remote server
|
||||
<KeyBinding keyDecl="Cmd:g" />
|
||||
</div>
|
||||
<div className="tip">
|
||||
<div className="icon-wrap">
|
||||
<MagnifyIcon enabled={false} />
|
||||
</div>
|
||||
Magnify a Block <KeyBinding keyDecl="Cmd:m" />
|
||||
</div>
|
||||
<div className="tip">
|
||||
<div className="icon-wrap">
|
||||
<i className="fa-solid fa-sharp fa-cog fa-fw" />
|
||||
</div>
|
||||
Block Settings
|
||||
</div>
|
||||
<div className="tip">
|
||||
<div className="icon-wrap">
|
||||
<i className="fa-solid fa-sharp fa-xmark-large fa-fw" />
|
||||
</div>
|
||||
Close Block <KeyBinding keyDecl="Cmd:w" />
|
||||
</div>
|
||||
|
||||
<div className="tip-section-header">Important Keybindings</div>
|
||||
|
||||
<div className="tip">
|
||||
<KeyBinding keyDecl="Cmd:t" />
|
||||
New Tab
|
||||
</div>
|
||||
<div className="tip">
|
||||
<KeyBinding keyDecl="Cmd:n" />
|
||||
New Terminal Block
|
||||
</div>
|
||||
<div className="tip">
|
||||
<KeyBinding keyDecl="Ctrl:Shift:Arrows" />
|
||||
Navigate Between Blocks
|
||||
</div>
|
||||
<div className="tip">
|
||||
<KeyBinding keyDecl="Ctrl:Shift:Digit" />
|
||||
Focus Nth Block
|
||||
</div>
|
||||
<div className="tip">
|
||||
<KeyBinding keyDecl="Cmd:Digit" />
|
||||
Switch To Nth Tab
|
||||
</div>
|
||||
|
||||
<div className="tip-section-header">wsh commands</div>
|
||||
<div className="tip">
|
||||
<div>
|
||||
<code>wsh view [filename|url]</code>
|
||||
<div style={{ marginTop: 5 }}>
|
||||
Run this command in the terminal to preview a file, directory, or web URL.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { KeyBinding, QuickTips };
|
@ -10,6 +10,7 @@ import { TosModal } from "./tos";
|
||||
|
||||
const ModalsRenderer = () => {
|
||||
const clientData = jotai.useAtomValue(atoms.client);
|
||||
const [tosOpen, setTosOpen] = jotai.useAtom(modalsModel.tosOpen);
|
||||
const [modals] = jotai.useAtom(modalsModel.modalsAtom);
|
||||
const rtn: JSX.Element[] = [];
|
||||
for (const modal of modals) {
|
||||
@ -18,12 +19,18 @@ const ModalsRenderer = () => {
|
||||
rtn.push(<ModalComponent key={modal.displayName} {...modal.props} />);
|
||||
}
|
||||
}
|
||||
if (!clientData.tosagreed) {
|
||||
if (tosOpen) {
|
||||
rtn.push(<TosModal key={TosModal.displayName} />);
|
||||
}
|
||||
useEffect(() => {
|
||||
if (!clientData.tosagreed) {
|
||||
setTosOpen(true);
|
||||
}
|
||||
}, [clientData]);
|
||||
useEffect(() => {
|
||||
globalStore.set(atoms.modalOpen, rtn.length > 0);
|
||||
});
|
||||
}, [rtn]);
|
||||
|
||||
return <>{rtn}</>;
|
||||
};
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
padding: 30px;
|
||||
width: 100%;
|
||||
|
||||
header.tos-header {
|
||||
flex-direction: column;
|
||||
@ -18,6 +19,7 @@
|
||||
border-bottom: none;
|
||||
padding: 0;
|
||||
margin-bottom: 36px;
|
||||
width: 100%;
|
||||
|
||||
.logo {
|
||||
margin-bottom: 10px;
|
||||
@ -55,6 +57,106 @@
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.tips-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
.tips-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
gap: 5px;
|
||||
|
||||
.tip-section-header {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 10px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tip {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.keybinding2 {
|
||||
font: var(--fixed-font);
|
||||
background-color: var(--highlight-bg-color);
|
||||
color: var(--main-text-color);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.keybinding-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.keybinding {
|
||||
display: inline-block;
|
||||
padding: 0.1em 0.4em;
|
||||
margin: 0 0.1em;
|
||||
font-family: "SF Pro Text", "Segoe UI", sans-serif;
|
||||
font-size: 0.85em;
|
||||
color: #e0e0e0;
|
||||
background-color: #333;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #444;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.keybinding3 {
|
||||
color: black;
|
||||
display: inline-block;
|
||||
padding: 0.2em 0.4em;
|
||||
min-width: 24px;
|
||||
height: 22px;
|
||||
margin: 0 0.1em;
|
||||
font-family: "SF Pro Text", "Segoe UI", sans-serif;
|
||||
font-size: 0.9em;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
background-color: #ddd;
|
||||
color: var(--invert-text-color);
|
||||
box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.icon-wrap {
|
||||
background-color: var(--highlight-bg-color);
|
||||
padding: 2px;
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 12px;
|
||||
border-radius: 2px;
|
||||
margin-right: 5px;
|
||||
|
||||
svg {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
left: 1px;
|
||||
height: 13px;
|
||||
#arrow1,
|
||||
#arrow2 {
|
||||
fill: var(--main-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-section {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
@ -9,13 +9,156 @@ import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { FlexiModal } from "./modal";
|
||||
|
||||
import { QuickTips } from "@/app/element/quicktips";
|
||||
import { atoms } from "@/app/store/global";
|
||||
import { modalsModel } from "@/app/store/modalmodel";
|
||||
import { RpcApi } from "@/app/store/wshclientapi";
|
||||
import { WindowRpcClient } from "@/app/store/wshrpcutil";
|
||||
import { atom, PrimitiveAtom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
||||
import "./tos.less";
|
||||
|
||||
const pageNumAtom: PrimitiveAtom<number> = atom<number>(1);
|
||||
|
||||
const ModalPage1 = () => {
|
||||
const settings = useAtomValue(atoms.settingsAtom);
|
||||
const clientData = useAtomValue(atoms.client);
|
||||
const [tosOpen, setTosOpen] = useAtom(modalsModel.tosOpen);
|
||||
const [telemetryEnabled, setTelemetryEnabled] = useState<boolean>(!!settings["telemetry:enabled"]);
|
||||
const setPageNum = useSetAtom(pageNumAtom);
|
||||
|
||||
const acceptTos = () => {
|
||||
if (!clientData.tosagreed) {
|
||||
services.ClientService.AgreeTos();
|
||||
}
|
||||
setPageNum(2);
|
||||
};
|
||||
|
||||
const setTelemetry = (value: boolean) => {
|
||||
RpcApi.SetConfigCommand(WindowRpcClient, { "telemetry:enabled": value })
|
||||
.then(() => {
|
||||
setTelemetryEnabled(value);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("failed to set telemetry:", error);
|
||||
});
|
||||
};
|
||||
|
||||
const label = telemetryEnabled ? "Telemetry Enabled" : "Telemetry Disabled";
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="modal-header tos-header unselectable">
|
||||
<div className="logo">
|
||||
<Logo />
|
||||
</div>
|
||||
<div className="modal-title">Welcome to Wave Terminal</div>
|
||||
</header>
|
||||
<div className="modal-content tos-content unselectable">
|
||||
<div className="content-section">
|
||||
<div className="icon-wrapper">
|
||||
<a target="_blank" href="https://github.com/wavetermdev/waveterm" rel={"noopener"}>
|
||||
<i className="icon fa-brands fa-github"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className="content-section-inner">
|
||||
<div className="content-section-title">Support us on GitHub</div>
|
||||
<div className="content-section-text">
|
||||
We're <i>open source</i> and committed to providing a free terminal for individual users.
|
||||
Please show your support by giving us a star on{" "}
|
||||
<a target="_blank" href="https://github.com/wavetermdev/waveterm" rel={"noopener"}>
|
||||
Github (wavetermdev/waveterm)
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-section">
|
||||
<div className="icon-wrapper">
|
||||
<a target="_blank" href="https://discord.gg/XfvZ334gwU" rel={"noopener"}>
|
||||
<i className="icon fa-solid fa-people-group"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className="content-section-inner">
|
||||
<div className="content-section-title">Join our Community</div>
|
||||
<div className="content-section-text">
|
||||
Get help, submit feature requests, report bugs, or just chat with fellow terminal
|
||||
enthusiasts.
|
||||
<br />
|
||||
<a target="_blank" href="https://discord.gg/XfvZ334gwU" rel={"noopener"}>
|
||||
Join the Wave Discord Channel
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-section">
|
||||
<div className="icon-wrapper">
|
||||
<i className="icon fa-solid fa-chart-line"></i>
|
||||
</div>
|
||||
<div className="content-section-inner">
|
||||
<div className="content-section-title">Telemetry</div>
|
||||
<div className="content-section-text">
|
||||
We collect minimal anonymous{" "}
|
||||
<a target="_blank" href="https://docs.waveterm.dev/reference/telemetry" rel={"noopener"}>
|
||||
telemetry data
|
||||
</a>{" "}
|
||||
to help us understand how people are using Wave (
|
||||
<a
|
||||
className="plain-link"
|
||||
target="_blank"
|
||||
href="https://waveterm.dev/privacy"
|
||||
rel="noopener"
|
||||
>
|
||||
Privacy Policy
|
||||
</a>
|
||||
).
|
||||
</div>
|
||||
<Toggle checked={telemetryEnabled} onChange={setTelemetry} label={label} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer className="unselectable">
|
||||
<div className="button-wrapper">
|
||||
<Button className="font-weight-600 primary" onClick={acceptTos}>
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const ModalPage2 = () => {
|
||||
const [tosOpen, setTosOpen] = useAtom(modalsModel.tosOpen);
|
||||
|
||||
const handleGetStarted = () => {
|
||||
setTosOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="modal-header tos-header unselectable">
|
||||
<div className="logo">
|
||||
<Logo />
|
||||
</div>
|
||||
<div className="modal-title">Icons and Keybindings</div>
|
||||
</header>
|
||||
<div className="modal-content tos-content unselectable">
|
||||
<QuickTips />
|
||||
</div>
|
||||
<footer className="unselectable">
|
||||
<div className="button-wrapper">
|
||||
<Button className="font-weight-600 primary" onClick={handleGetStarted}>
|
||||
Get Started
|
||||
</Button>
|
||||
</div>
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const TosModal = () => {
|
||||
const [telemetryEnabled, setTelemetryEnabled] = useState<boolean>(true);
|
||||
const modalRef = useRef<HTMLDivElement | null>(null);
|
||||
const [pageNum, setPageNum] = useAtom(pageNumAtom);
|
||||
const clientData = useAtomValue(atoms.client);
|
||||
|
||||
const updateModalHeight = () => {
|
||||
const windowHeight = window.innerHeight;
|
||||
@ -30,6 +173,16 @@ const TosModal = () => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// on unmount, always reset pagenum
|
||||
if (clientData.tosagreed) {
|
||||
setPageNum(2);
|
||||
}
|
||||
return () => {
|
||||
setPageNum(1);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
updateModalHeight(); // Run on initial render
|
||||
|
||||
@ -39,118 +192,10 @@ const TosModal = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const acceptTos = () => {
|
||||
services.ClientService.AgreeTos();
|
||||
};
|
||||
|
||||
const setTelemetry = (value: boolean) => {
|
||||
RpcApi.SetConfigCommand(WindowRpcClient, { "telemetry:enabled": value })
|
||||
.then(() => {
|
||||
setTelemetryEnabled(value);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("failed to set telemetry:", error);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
services.FileService.GetFullConfig()
|
||||
.then((data) => {
|
||||
if ("telemetry:enabled" in data.settings) {
|
||||
setTelemetryEnabled(true);
|
||||
} else {
|
||||
setTelemetryEnabled(false);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("failed to get config:", error);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const label = telemetryEnabled ? "Telemetry Enabled" : "Telemetry Disabled";
|
||||
|
||||
return (
|
||||
<FlexiModal className="tos-modal" ref={modalRef}>
|
||||
<OverlayScrollbarsComponent className="modal-inner" options={{ scrollbars: { autoHide: "leave" } }}>
|
||||
<header className="modal-header tos-header unselectable">
|
||||
<div className="logo">
|
||||
<Logo />
|
||||
</div>
|
||||
<div className="modal-title">Welcome to Wave Terminal</div>
|
||||
</header>
|
||||
<div className="modal-content tos-content unselectable">
|
||||
<div className="content-section">
|
||||
<div className="icon-wrapper">
|
||||
<a target="_blank" href="https://github.com/wavetermdev/waveterm" rel={"noopener"}>
|
||||
<i className="icon fa-brands fa-github"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className="content-section-inner">
|
||||
<div className="content-section-title">Support us on GitHub</div>
|
||||
<div className="content-section-text">
|
||||
We're <i>open source</i> and committed to providing a free terminal for individual
|
||||
users. Please show your support by giving us a star on{" "}
|
||||
<a target="_blank" href="https://github.com/wavetermdev/waveterm" rel={"noopener"}>
|
||||
Github (wavetermdev/waveterm)
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-section">
|
||||
<div className="icon-wrapper">
|
||||
<a target="_blank" href="https://discord.gg/XfvZ334gwU" rel={"noopener"}>
|
||||
<i className="icon fa-solid fa-people-group"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className="content-section-inner">
|
||||
<div className="content-section-title">Join our Community</div>
|
||||
<div className="content-section-text">
|
||||
Get help, submit feature requests, report bugs, or just chat with fellow terminal
|
||||
enthusiasts.
|
||||
<br />
|
||||
<a target="_blank" href="https://discord.gg/XfvZ334gwU" rel={"noopener"}>
|
||||
Join the Wave Discord Channel
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-section">
|
||||
<div className="icon-wrapper">
|
||||
<i className="icon fa-solid fa-chart-line"></i>
|
||||
</div>
|
||||
<div className="content-section-inner">
|
||||
<div className="content-section-title">Telemetry</div>
|
||||
<div className="content-section-text">
|
||||
We collect minimal anonymous{" "}
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://docs.waveterm.dev/reference/telemetry"
|
||||
rel={"noopener"}
|
||||
>
|
||||
telemetry data
|
||||
</a>{" "}
|
||||
to help us understand how people are using Wave (
|
||||
<a
|
||||
className="plain-link"
|
||||
target="_blank"
|
||||
href="https://waveterm.dev/privacy"
|
||||
rel="noopener"
|
||||
>
|
||||
Privacy Policy
|
||||
</a>
|
||||
).
|
||||
</div>
|
||||
<Toggle checked={telemetryEnabled} onChange={setTelemetry} label={label} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer className="unselectable">
|
||||
<div className="button-wrapper">
|
||||
<Button className="font-weight-600" onClick={acceptTos}>
|
||||
Get Started
|
||||
</Button>
|
||||
</div>
|
||||
</footer>
|
||||
{pageNum === 1 ? <ModalPage1 /> : <ModalPage2 />}
|
||||
</OverlayScrollbarsComponent>
|
||||
</FlexiModal>
|
||||
);
|
||||
|
@ -6,8 +6,10 @@ import { globalStore } from "./global";
|
||||
|
||||
class ModalsModel {
|
||||
modalsAtom: jotai.PrimitiveAtom<Array<{ displayName: string; props?: any }>>;
|
||||
tosOpen: jotai.PrimitiveAtom<boolean>;
|
||||
|
||||
constructor() {
|
||||
this.tosOpen = jotai.atom(false);
|
||||
this.modalsAtom = jotai.atom([]);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,10 @@
|
||||
--block-bg-solid-color: rgb(0, 0, 0);
|
||||
--block-border-radius: 8px;
|
||||
|
||||
--keybinding-color: #e0e0e0;
|
||||
--keybinding-bg-color: #333;
|
||||
--keybinding-border-color: #444;
|
||||
|
||||
/* scrollbar colors */
|
||||
--scrollbar-background-color: transparent;
|
||||
--scrollbar-thumb-color: rgba(255, 255, 255, 0.15);
|
||||
|
@ -148,7 +148,7 @@ a codeedit block which you can use to quickly edit the file using Wave's embedde
|
||||
### edit
|
||||
|
||||
\`\`\`
|
||||
wsh edit [path]
|
||||
wsh editor [path]
|
||||
\`\`\`
|
||||
|
||||
This will open up codeedit for the specified file. This is useful for quickly editing files on a local or remote machine in our graphical editor. This command will wait until the file is closed before exiting (unlike \`view\`) so you can set your \`$EDITOR\` to \`wsh edit\` for a seamless experience. You can combine this with a \`-m\` flag to open the editor in magnified mode.
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
registerElectronReinjectKeyHandler,
|
||||
registerGlobalKeys,
|
||||
} from "@/app/store/keymodel";
|
||||
import { modalsModel } from "@/app/store/modalmodel";
|
||||
import { FileService, ObjectService } from "@/app/store/services";
|
||||
import { RpcApi } from "@/app/store/wshclientapi";
|
||||
import { initWshrpc, WindowRpcClient } from "@/app/store/wshrpcutil";
|
||||
@ -52,6 +53,7 @@ loadFonts();
|
||||
(window as any).countersClear = countersClear;
|
||||
(window as any).getLayoutModelForActiveTab = getLayoutModelForActiveTab;
|
||||
(window as any).pushFlashError = pushFlashError;
|
||||
(window as any).modalsModel = modalsModel;
|
||||
|
||||
document.title = `The Next Wave (${windowId.substring(0, 8)})`;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user