mirror of
https://github.com/veeso/termscp.git
synced 2026-07-15 04:23:50 +02:00
feat(install): add Windows PowerShell installer and copy buttons on site
Add install.ps1 mirroring install.sh for Windows: arch detection, release zip download, binary extraction, user PATH update. - copy install.ps1 to site public/ at build time (copy-install.mjs) - serve /install.ps1 with text/plain Content-Type (vercel.json) - add PowerShell one-liner to install page and README - bump install.ps1 default version in bump_version.sh - add CopyButton component next to every install command line
This commit is contained in:
54
site/src/components/CopyButton.astro
Normal file
54
site/src/components/CopyButton.astro
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
interface Props {
|
||||
text: string;
|
||||
class?: string;
|
||||
}
|
||||
const { text, class: className } = Astro.props;
|
||||
---
|
||||
<button
|
||||
type="button"
|
||||
class:list={[
|
||||
"copy-btn rounded p-1.5 text-overlay transition-colors hover:bg-mantle hover:text-text",
|
||||
className,
|
||||
]}
|
||||
data-copy={text}
|
||||
aria-label="Copy command to clipboard"
|
||||
title="Copy"
|
||||
>
|
||||
<svg class="copy-icon h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
|
||||
</svg>
|
||||
<svg class="check-icon hidden h-4 w-4 text-green" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M20 6 9 17l-5-5"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<script>
|
||||
const RESET_DELAY_MS = 1500;
|
||||
|
||||
const handleCopy = async (button: HTMLElement) => {
|
||||
const text = button.getAttribute("data-copy") ?? "";
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
const copyIcon = button.querySelector(".copy-icon");
|
||||
const checkIcon = button.querySelector(".check-icon");
|
||||
copyIcon?.classList.add("hidden");
|
||||
checkIcon?.classList.remove("hidden");
|
||||
|
||||
window.setTimeout(() => {
|
||||
copyIcon?.classList.remove("hidden");
|
||||
checkIcon?.classList.add("hidden");
|
||||
}, RESET_DELAY_MS);
|
||||
};
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
const button = (event.target as HTMLElement)?.closest<HTMLElement>(".copy-btn");
|
||||
if (button) {
|
||||
handleCopy(button);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import CopyButton from "./CopyButton.astro";
|
||||
|
||||
interface Method { id: string; label: string; cmd: string; }
|
||||
interface Props { methods: Method[]; }
|
||||
const { methods } = Astro.props;
|
||||
@@ -14,11 +16,10 @@ const { methods } = Astro.props;
|
||||
))}
|
||||
</div>
|
||||
{methods.map((m, i) => (
|
||||
<pre
|
||||
class="install-panel m-0 overflow-auto bg-base px-4 py-4 text-sm text-text"
|
||||
data-id={m.id}
|
||||
hidden={i !== 0}
|
||||
><code>{m.cmd}</code></pre>
|
||||
<div class="install-panel relative" data-id={m.id} hidden={i !== 0}>
|
||||
<pre class="m-0 overflow-auto bg-base px-4 py-4 pr-12 text-sm text-text"><code>{m.cmd}</code></pre>
|
||||
<CopyButton text={m.cmd} class="absolute right-2 top-2" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<script is:inline>
|
||||
|
||||
@@ -3,9 +3,11 @@ import Base from "../layouts/Base.astro";
|
||||
import Nav from "../components/Nav.astro";
|
||||
import Footer from "../components/Footer.astro";
|
||||
import InstallTabs from "../components/InstallTabs.astro";
|
||||
import CopyButton from "../components/CopyButton.astro";
|
||||
import { DOCS_URL } from "../consts";
|
||||
|
||||
const script = "curl --proto '=https' --tlsv1.2 -sSLf https://termscp.rs/install.sh | sh";
|
||||
const psScript = "irm https://termscp.rs/install.ps1 | iex";
|
||||
|
||||
const methods = [
|
||||
{ id: "cargo", label: "Cargo", cmd: "cargo install termscp --locked" },
|
||||
@@ -28,10 +30,24 @@ const methods = [
|
||||
<div class="flex items-center gap-2 border-b border-line px-3 py-2 text-xs text-overlay">
|
||||
<span class="text-green">$</span> Linux · macOS · BSD
|
||||
</div>
|
||||
<pre class="m-0 overflow-auto bg-base px-4 py-4 text-sm text-text"><code>{script}</code></pre>
|
||||
<div class="relative">
|
||||
<pre class="m-0 overflow-auto bg-base px-4 py-4 pr-12 text-sm text-text"><code>{script}</code></pre>
|
||||
<CopyButton text={script} class="absolute right-2 top-2" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-overlay">Requires <span class="text-text">curl</span>. macOS uses Homebrew if available, otherwise builds from source.</p>
|
||||
|
||||
<div class="mt-6 rounded-lg border border-line bg-mantle p-1">
|
||||
<div class="flex items-center gap-2 border-b border-line px-3 py-2 text-xs text-overlay">
|
||||
<span class="text-green">></span> Windows (PowerShell)
|
||||
</div>
|
||||
<div class="relative">
|
||||
<pre class="m-0 overflow-auto bg-base px-4 py-4 pr-12 text-sm text-text"><code>{psScript}</code></pre>
|
||||
<CopyButton text={psScript} class="absolute right-2 top-2" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-overlay">Downloads the latest release and adds <span class="text-text">termscp</span> to your user PATH.</p>
|
||||
|
||||
<h2 class="mt-10 mb-3 text-lg text-text">Package managers</h2>
|
||||
<InstallTabs methods={methods} />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user