Skip to content

Commit a9d7558

Browse files
sanityclaude
andauthored
feat: auto-detect OS on quickstart page with tabbed install instructions (#20)
* docs: update Windows quickstart to use setup wizard Replace the old `cargo install freenet` instructions with a direct download link. Running freenet.exe now shows a setup wizard that handles installation automatically (added in freenet-core#3680). Closes #19 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: link directly to freenet.exe instead of zip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: auto-detect OS on quickstart page with tabbed install instructions Adds an os-install shortcode that detects the visitor's OS via navigator.platform and shows the matching install tab by default. All three options (Windows, macOS, Linux) remain accessible as tabs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add accessibility, JS fallback, and modern OS detection - Add ARIA roles/attributes for screen reader support (tablist, tab, tabpanel) - Default Linux tab active in HTML so content is visible without JS - Use navigator.userAgentData with navigator.platform fallback - Add aria-hidden to decorative SVG icons Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 28df47d commit a9d7558

2 files changed

Lines changed: 155 additions & 19 deletions

File tree

hugo-site/content/quickstart/_index.md

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,7 @@ Get started with Freenet in minutes. Install the software and join River—the w
1616

1717
## Step 1: Install Freenet
1818

19-
### Linux & macOS
20-
21-
Run this command in your terminal:
22-
23-
```bash
24-
curl -fsSL https://freenet.org/install.sh | sh
25-
```
26-
27-
This downloads and installs Freenet, then starts it as a background service.
28-
29-
### Windows
30-
31-
Install from source with [Cargo](https://rustup.rs/):
32-
33-
```bash
34-
cargo install freenet
35-
```
36-
37-
Then start Freenet with `freenet network`.
19+
{{< os-install >}}
3820

3921
## Step 2: Join Freenet Official
4022

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<style>
2+
.os-install-tabs {
3+
margin: 1.5rem 0;
4+
}
5+
6+
.os-install-tabs .tab-buttons {
7+
display: flex;
8+
gap: 0;
9+
border-bottom: 2px solid #e5e7eb;
10+
margin-bottom: 1.25rem;
11+
}
12+
13+
.os-install-tabs .tab-btn {
14+
padding: 0.625rem 1.25rem;
15+
border: none;
16+
background: none;
17+
cursor: pointer;
18+
font-size: 1rem;
19+
font-weight: 500;
20+
color: #6b7280;
21+
border-bottom: 2px solid transparent;
22+
margin-bottom: -2px;
23+
transition: color 0.2s, border-color 0.2s;
24+
display: flex;
25+
align-items: center;
26+
gap: 0.5rem;
27+
}
28+
29+
.os-install-tabs .tab-btn:hover {
30+
color: #0066CC;
31+
}
32+
33+
.os-install-tabs .tab-btn.active {
34+
color: #0066CC;
35+
border-bottom-color: #0066CC;
36+
}
37+
38+
.os-install-tabs .tab-btn .os-icon {
39+
width: 1.1em;
40+
height: 1.1em;
41+
display: inline-block;
42+
}
43+
44+
.os-install-tabs .tab-pane {
45+
display: none;
46+
}
47+
48+
.os-install-tabs .tab-pane.active {
49+
display: block;
50+
}
51+
52+
.os-install-tabs .tab-pane p {
53+
margin-bottom: 0.75rem;
54+
}
55+
56+
.os-install-tabs .tab-pane pre {
57+
margin-bottom: 0.75rem;
58+
}
59+
60+
@media (prefers-color-scheme: dark) {
61+
.os-install-tabs .tab-buttons {
62+
border-bottom-color: #374151;
63+
}
64+
65+
.os-install-tabs .tab-btn {
66+
color: #9ca3af;
67+
}
68+
69+
.os-install-tabs .tab-btn:hover,
70+
.os-install-tabs .tab-btn.active {
71+
color: #4da6ff;
72+
}
73+
74+
.os-install-tabs .tab-btn.active {
75+
border-bottom-color: #4da6ff;
76+
}
77+
}
78+
</style>
79+
80+
<div class="os-install-tabs">
81+
<div class="tab-buttons" role="tablist" aria-label="Operating system">
82+
<button class="tab-btn" data-os="windows" type="button" role="tab" aria-selected="false" aria-controls="os-pane-windows" id="os-tab-windows">
83+
<svg class="os-icon" aria-hidden="true" viewBox="0 0 24 24" fill="currentColor"><path d="M0 3.449L9.75 2.1v9.451H0m10.949-9.602L24 0v11.4H10.949M0 12.6h9.75v9.451L0 20.699M10.949 12.6H24V24l-12.9-1.801"/></svg>
84+
Windows
85+
</button>
86+
<button class="tab-btn" data-os="mac" type="button" role="tab" aria-selected="false" aria-controls="os-pane-mac" id="os-tab-mac">
87+
<svg class="os-icon" aria-hidden="true" viewBox="0 0 24 24" fill="currentColor"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.8-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/></svg>
88+
macOS
89+
</button>
90+
<button class="tab-btn active" data-os="linux" type="button" role="tab" aria-selected="true" aria-controls="os-pane-linux" id="os-tab-linux">
91+
<svg class="os-icon" aria-hidden="true" viewBox="0 0 24 24" fill="currentColor"><path d="M20.581 19.049c-.55-.446-.336-1.431-.907-1.917.553-3.365-.997-6.331-2.845-8.232-1.551-1.595-1.639-3.743-1.591-4.899.115-2.795-1.322-4-2.235-4-1.235 0-2.476 1.41-2.259 4.186.045.571-.053 3.171-1.591 4.713-1.918 1.924-3.443 5.111-2.845 8.232-.571.486-.357 1.471-.907 1.917-1.036.838-1.275 2.243-.186 2.58.909.282 2.128.13 2.53-1.136.154-.484-.07-1.079.026-1.721.157-1.043.481-.878.763-.878.566 0 .628.439.64 1.121.014.794.139 1.478.396 1.758 1.089 1.186 3.267 1.186 4.357 0 .256-.28.381-.964.396-1.758.011-.682.073-1.121.64-1.121.281 0 .606-.165.763.878.095.642-.128 1.237.026 1.721.402 1.266 1.621 1.418 2.53 1.136 1.089-.337.85-1.742-.186-2.58z"/></svg>
92+
Linux
93+
</button>
94+
</div>
95+
96+
<div class="tab-pane" data-os="windows" role="tabpanel" id="os-pane-windows" aria-labelledby="os-tab-windows">
97+
<p><a href="https://github.com/freenet/freenet-core/releases/latest/download/freenet.exe">Download freenet.exe</a>
98+
and run it. The setup wizard will guide you through installation, then start Freenet as a background
99+
service with a system tray icon.</p>
100+
</div>
101+
102+
<div class="tab-pane" data-os="mac" role="tabpanel" id="os-pane-mac" aria-labelledby="os-tab-mac">
103+
<p>Run this command in your terminal:</p>
104+
<pre><code class="language-bash">curl -fsSL https://freenet.org/install.sh | sh</code></pre>
105+
<p>This downloads and installs Freenet, then starts it as a background service.</p>
106+
</div>
107+
108+
<div class="tab-pane active" data-os="linux" role="tabpanel" id="os-pane-linux" aria-labelledby="os-tab-linux">
109+
<p>Run this command in your terminal:</p>
110+
<pre><code class="language-bash">curl -fsSL https://freenet.org/install.sh | sh</code></pre>
111+
<p>This downloads and installs Freenet, then starts it as a background service.</p>
112+
</div>
113+
</div>
114+
115+
<script>
116+
(function() {
117+
function detectOS() {
118+
// Modern API (Chrome 93+, Edge 93+, Opera 79+)
119+
if (navigator.userAgentData && navigator.userAgentData.platform) {
120+
var p = navigator.userAgentData.platform;
121+
if (/Win/i.test(p)) return 'windows';
122+
if (/mac/i.test(p)) return 'mac';
123+
return 'linux';
124+
}
125+
// Legacy fallback
126+
var ua = navigator.userAgent || '';
127+
var platform = navigator.platform || '';
128+
if (/Win/.test(platform)) return 'windows';
129+
if (/Mac/.test(platform) || /iPhone|iPad/.test(ua)) return 'mac';
130+
return 'linux';
131+
}
132+
133+
function activateTab(os) {
134+
var container = document.querySelector('.os-install-tabs');
135+
if (!container) return;
136+
container.querySelectorAll('.tab-btn').forEach(function(btn) {
137+
var isActive = btn.getAttribute('data-os') === os;
138+
btn.classList.toggle('active', isActive);
139+
btn.setAttribute('aria-selected', isActive ? 'true' : 'false');
140+
});
141+
container.querySelectorAll('.tab-pane').forEach(function(pane) {
142+
pane.classList.toggle('active', pane.getAttribute('data-os') === os);
143+
});
144+
}
145+
146+
document.querySelectorAll('.os-install-tabs .tab-btn').forEach(function(btn) {
147+
btn.addEventListener('click', function() {
148+
activateTab(this.getAttribute('data-os'));
149+
});
150+
});
151+
152+
activateTab(detectOS());
153+
})();
154+
</script>

0 commit comments

Comments
 (0)