2024-07-30 20:44:19 +02:00
|
|
|
|
// Copyright 2024, Command Line Inc.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
|
|
import Logo from "@/app/asset/logo.svg";
|
|
|
|
|
import { Button } from "@/app/element/button";
|
2024-08-27 03:03:32 +02:00
|
|
|
|
import { Toggle } from "@/app/element/toggle";
|
2024-07-30 20:44:19 +02:00
|
|
|
|
import * as services from "@/store/services";
|
2024-09-13 08:10:18 +02:00
|
|
|
|
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
|
|
|
|
|
import { useEffect, useRef, useState } from "react";
|
2024-07-30 20:44:19 +02:00
|
|
|
|
import { FlexiModal } from "./modal";
|
|
|
|
|
|
2024-09-17 08:45:47 +02:00
|
|
|
|
import { QuickTips } from "@/app/element/quicktips";
|
2024-09-26 00:52:12 +02:00
|
|
|
|
import { atoms, getApi } from "@/app/store/global";
|
2024-09-17 08:45:47 +02:00
|
|
|
|
import { modalsModel } from "@/app/store/modalmodel";
|
2024-12-06 03:09:54 +01:00
|
|
|
|
import { fireAndForget } from "@/util/util";
|
2024-09-17 08:45:47 +02:00
|
|
|
|
import { atom, PrimitiveAtom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
2024-11-22 01:05:04 +01:00
|
|
|
|
import "./tos.scss";
|
2024-07-30 20:44:19 +02:00
|
|
|
|
|
2024-09-17 08:45:47 +02:00
|
|
|
|
const pageNumAtom: PrimitiveAtom<number> = atom<number>(1);
|
2024-09-13 08:10:18 +02:00
|
|
|
|
|
2024-09-17 08:45:47 +02:00
|
|
|
|
const ModalPage1 = () => {
|
|
|
|
|
const settings = useAtomValue(atoms.settingsAtom);
|
|
|
|
|
const clientData = useAtomValue(atoms.client);
|
|
|
|
|
const [telemetryEnabled, setTelemetryEnabled] = useState<boolean>(!!settings["telemetry:enabled"]);
|
|
|
|
|
const setPageNum = useSetAtom(pageNumAtom);
|
2024-09-11 18:26:43 +02:00
|
|
|
|
|
2024-07-30 20:44:19 +02:00
|
|
|
|
const acceptTos = () => {
|
2024-09-17 08:45:47 +02:00
|
|
|
|
if (!clientData.tosagreed) {
|
2024-12-06 03:09:54 +01:00
|
|
|
|
fireAndForget(services.ClientService.AgreeTos);
|
2024-09-17 08:45:47 +02:00
|
|
|
|
}
|
|
|
|
|
setPageNum(2);
|
2024-07-30 20:44:19 +02:00
|
|
|
|
};
|
|
|
|
|
|
2024-09-13 08:10:18 +02:00
|
|
|
|
const setTelemetry = (value: boolean) => {
|
2024-12-06 03:09:54 +01:00
|
|
|
|
fireAndForget(() =>
|
|
|
|
|
services.ClientService.TelemetryUpdate(value).then(() => {
|
2024-09-11 18:26:43 +02:00
|
|
|
|
setTelemetryEnabled(value);
|
|
|
|
|
})
|
2024-12-06 03:09:54 +01:00
|
|
|
|
);
|
2024-09-13 08:10:18 +02:00
|
|
|
|
};
|
2024-09-03 05:21:35 +02:00
|
|
|
|
|
2024-09-13 08:10:18 +02:00
|
|
|
|
const label = telemetryEnabled ? "Telemetry Enabled" : "Telemetry Disabled";
|
2024-09-11 18:26:43 +02:00
|
|
|
|
|
2024-07-30 20:44:19 +02:00
|
|
|
|
return (
|
2024-09-17 08:45:47 +02:00
|
|
|
|
<>
|
|
|
|
|
<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>
|
2024-07-30 20:44:19 +02:00
|
|
|
|
</div>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
<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{" "}
|
2024-07-30 20:44:19 +02:00
|
|
|
|
<a target="_blank" href="https://github.com/wavetermdev/waveterm" rel={"noopener"}>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
Github (wavetermdev/waveterm)
|
2024-07-30 20:44:19 +02:00
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
</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 />
|
2024-09-13 08:10:18 +02:00
|
|
|
|
<a target="_blank" href="https://discord.gg/XfvZ334gwU" rel={"noopener"}>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
Join the Wave Discord Channel
|
2024-07-30 20:44:19 +02:00
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
</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{" "}
|
2024-10-21 20:56:29 +02:00
|
|
|
|
<a target="_blank" href="https://docs.waveterm.dev/telemetry" rel={"noopener"}>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
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>
|
|
|
|
|
).
|
2024-07-30 20:44:19 +02:00
|
|
|
|
</div>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
<Toggle checked={telemetryEnabled} onChange={setTelemetry} label={label} />
|
2024-07-30 20:44:19 +02:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
</div>
|
|
|
|
|
<footer className="unselectable">
|
|
|
|
|
<div className="button-wrapper">
|
2024-09-18 07:38:17 +02:00
|
|
|
|
<Button className="font-weight-600" onClick={acceptTos}>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
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">
|
2024-09-18 07:38:17 +02:00
|
|
|
|
<Button className="font-weight-600" onClick={handleGetStarted}>
|
2024-09-17 08:45:47 +02:00
|
|
|
|
Get Started
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</footer>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-26 00:52:12 +02:00
|
|
|
|
const ModalPageLegacy = () => {
|
|
|
|
|
const setPageNum = useSetAtom(pageNumAtom);
|
|
|
|
|
const handleContinue = () => {
|
|
|
|
|
setPageNum(1);
|
|
|
|
|
};
|
|
|
|
|
const handleDownloadLegacy = () => {
|
|
|
|
|
getApi().openExternal("https://waveterm.dev/download-legacy?ref=v7upgrade");
|
|
|
|
|
};
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<header className="modal-header tos-header unselectable">
|
|
|
|
|
<div className="logo">
|
|
|
|
|
<Logo />
|
|
|
|
|
</div>
|
2024-11-16 01:09:26 +01:00
|
|
|
|
<div className="modal-title">Welcome to Wave v0.9</div>
|
2024-09-26 00:52:12 +02:00
|
|
|
|
</header>
|
|
|
|
|
<div className="modal-content tos-content unselectable">
|
|
|
|
|
<div className="item">
|
2024-11-16 01:09:26 +01:00
|
|
|
|
We’re excited to announce the release of Wave Terminal v0.9. This update introduces a brand-new
|
2024-09-26 00:52:12 +02:00
|
|
|
|
layout engine, featuring drag-and-drop screen splitting with flexible block sizing and positioning.
|
|
|
|
|
We've also integrated powerful tools like file previews, an editor, web integration, and AI, all
|
|
|
|
|
designed to keep you focused and minimize context switching. And for the first time, Wave Terminal
|
|
|
|
|
runs <b>natively on Windows</b>!
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
2024-11-16 01:09:26 +01:00
|
|
|
|
Wave v0.9 is less opinionated, giving you the freedom to use your standard terminal prompt and
|
2024-09-26 00:52:12 +02:00
|
|
|
|
command completions, while supporting all shells (not just bash/zsh). We've also improved
|
|
|
|
|
compatibility with ohmyzsh packages, removing some of the friction users experienced. It’s faster,
|
|
|
|
|
more performant, and provides a stronger foundation for you to build your own blocks and widgets in
|
|
|
|
|
the future.
|
|
|
|
|
</div>
|
|
|
|
|
<div className="item">
|
|
|
|
|
The new build is a fresh start, and a clean break from the current version. As such, your history,
|
|
|
|
|
settings, and configuration will <i>not</i> be carried over. If you'd like to continue to run the
|
|
|
|
|
legacy version, you will need to download it separately.
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<footer className="unselectable">
|
|
|
|
|
<div className="button-wrapper">
|
|
|
|
|
<Button className="outlined grey" onClick={handleDownloadLegacy}>
|
|
|
|
|
Download WaveLegacy
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Button className="font-weight-600" onClick={handleContinue}>
|
|
|
|
|
Continue
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</footer>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-17 08:45:47 +02:00
|
|
|
|
const TosModal = () => {
|
|
|
|
|
const modalRef = useRef<HTMLDivElement | null>(null);
|
|
|
|
|
const [pageNum, setPageNum] = useAtom(pageNumAtom);
|
|
|
|
|
const clientData = useAtomValue(atoms.client);
|
|
|
|
|
|
|
|
|
|
const updateModalHeight = () => {
|
|
|
|
|
const windowHeight = window.innerHeight;
|
|
|
|
|
if (modalRef.current) {
|
|
|
|
|
const modalHeight = modalRef.current.offsetHeight;
|
|
|
|
|
const maxHeight = windowHeight * 0.9;
|
|
|
|
|
if (maxHeight < modalHeight) {
|
|
|
|
|
modalRef.current.style.height = `${maxHeight}px`;
|
|
|
|
|
} else {
|
|
|
|
|
modalRef.current.style.height = "auto";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
// on unmount, always reset pagenum
|
2024-09-26 00:52:12 +02:00
|
|
|
|
if (!clientData.tosagreed && clientData.hasoldhistory) {
|
|
|
|
|
setPageNum(0);
|
|
|
|
|
} else if (clientData.tosagreed) {
|
2024-09-17 08:45:47 +02:00
|
|
|
|
setPageNum(2);
|
|
|
|
|
}
|
|
|
|
|
return () => {
|
|
|
|
|
setPageNum(1);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
updateModalHeight(); // Run on initial render
|
|
|
|
|
|
|
|
|
|
window.addEventListener("resize", updateModalHeight); // Run on window resize
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener("resize", updateModalHeight);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
2024-09-26 00:52:12 +02:00
|
|
|
|
let pageComp: React.JSX.Element = null;
|
|
|
|
|
switch (pageNum) {
|
|
|
|
|
case 0:
|
|
|
|
|
pageComp = <ModalPageLegacy />;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
pageComp = <ModalPage1 />;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
pageComp = <ModalPage2 />;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (pageComp == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-09-17 08:45:47 +02:00
|
|
|
|
return (
|
|
|
|
|
<FlexiModal className="tos-modal" ref={modalRef}>
|
|
|
|
|
<OverlayScrollbarsComponent className="modal-inner" options={{ scrollbars: { autoHide: "leave" } }}>
|
2024-09-26 00:52:12 +02:00
|
|
|
|
{pageComp}
|
2024-09-13 08:10:18 +02:00
|
|
|
|
</OverlayScrollbarsComponent>
|
2024-07-30 20:44:19 +02:00
|
|
|
|
</FlexiModal>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TosModal.displayName = "TosModal";
|
|
|
|
|
|
|
|
|
|
export { TosModal };
|