Skip to content

Commit 4b9e16d

Browse files
committed
v2.9.6: custom ToS, unpin bug fix, Android popup fixes
1 parent 508c42e commit 4b9e16d

14 files changed

Lines changed: 90 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). Haven uses [Sema
1111
1212
---
1313

14+
## [2.9.6] — 2026-04-07
15+
16+
### Added
17+
- **Custom Terms of Service** — admins can now add custom terms that appear above the default Haven ToS on the login page. Set via a new textarea in Admin Settings. Supports plain text with paragraph breaks, max 50,000 characters. Leave empty to show only the default ToS. (#5229)
18+
19+
### Fixed
20+
- **Unpin message visual bug** — unpinning a message while viewing the pinned messages panel no longer leaves the pin border on the message. The pinned panel item is also removed in real time and the count updates. (#5228)
21+
- **Android app popup "Don't show this again"** — the checkbox now persists correctly across sessions. Previously the v3 migration flag used sessionStorage, causing dismissals to reset on every new session.
22+
- **Android app popup layout** — moved the "NOW AVAILABLE" badge above the title instead of inline, and centered the title text.
23+
24+
---
25+
1426
## [2.9.5] — 2026-04-07
1527

1628
### Changed

docs/index.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,12 +1415,12 @@ <h2>Download Haven</h2>
14151415
</div>
14161416

14171417
<div class="download-card fade-in">
1418-
<h2>&#x2B21; Haven Server &mdash; v2.9.5</h2>
1418+
<h2>&#x2B21; Haven Server &mdash; v2.9.6</h2>
14191419
<p class="download-version">Latest stable release &middot; Windows, macOS &amp; Linux &middot; ~5 MB</p>
14201420

14211421
<div class="download-btn-group">
1422-
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.5.zip" class="btn btn-primary download-main">
1423-
<span class="icon">&#x2B07;</span> Download v2.9.5 (.zip)
1422+
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.6.zip" class="btn btn-primary download-main">
1423+
<span class="icon">&#x2B07;</span> Download v2.9.6 (.zip)
14241424
</a>
14251425
<div class="download-alt-links">
14261426
<a href="https://github.com/ancsemi/Haven" target="_blank">&#9965; View on GitHub</a>
@@ -1437,7 +1437,11 @@ <h2>&#x2B21; Haven Server &mdash; v2.9.5</h2>
14371437
<div class="version-list">
14381438
<div class="version-list-inner">
14391439
<div class="version-item">
1440-
<div><span class="v-name">v2.9.5</span><span class="v-tag latest">Latest</span></div>
1440+
<div><span class="v-name">v2.9.6</span><span class="v-tag latest">Latest</span></div>
1441+
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.6.zip">Download &rarr;</a>
1442+
</div>
1443+
<div class="version-item">
1444+
<div><span class="v-name">v2.9.5</span> &mdash; License changed to AGPL-3.0</div>
14411445
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.5.zip">Download &rarr;</a>
14421446
</div>
14431447
<div class="version-item">

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "haven",
3-
"version": "2.9.5",
3+
"version": "2.9.6",
44
"description": "Haven — self-hosted private chat for your server, your rules",
55
"license": "AGPL-3.0",
66
"main": "server.js",

public/app.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,12 @@ <h5 class="settings-section-subtitle">🤖 <span data-i18n="settings.admin.bots_
15741574
<p class="muted-text" data-i18n="settings.admin.no_bots">No bots configured</p>
15751575
</div>
15761576
</div>
1577+
<!-- Custom Terms of Service (Admin only) -->
1578+
<div class="admin-settings" id="section-custom-tos" style="margin-top:10px; padding-top:10px; border-top:1px solid var(--border);">
1579+
<h5 class="settings-section-subtitle">⚖️ <span data-i18n="settings.admin.custom_tos_title">Custom Terms of Service</span></h5>
1580+
<small class="settings-hint" data-i18n="settings.admin.custom_tos_hint">Add custom terms that appear before the default ToS on the login page. Supports plain text. Leave empty to show only the default Haven ToS.</small>
1581+
<textarea id="custom-tos-input" class="settings-textarea" rows="6" maxlength="50000" placeholder="Enter your custom terms of service..." style="margin-top:8px;width:100%;resize:vertical;min-height:80px;font-size:12px;padding:8px;border-radius:6px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-primary);font-family:inherit;"></textarea>
1582+
</div>
15771583
<!-- Discord Import (Admin only) -->
15781584
<div class="admin-settings" id="section-import" style="margin-top:10px; padding-top:10px; border-top:1px solid var(--border);">
15791585
<h5 class="settings-section-subtitle">📦 <span data-i18n="settings.admin.import_title">Discord Import</span></h5>
@@ -2464,7 +2470,8 @@ <h3>🔐 <span data-i18n="modals.e2e_password.title">Password Required</span></h
24642470
<div class="modal-overlay" id="android-beta-modal" style="display:none">
24652471
<div class="modal android-beta-promo">
24662472
<div class="android-beta-promo-icon">📱</div>
2467-
<h3 class="android-beta-promo-title"><span data-i18n="modals.android_beta.title">Amni-Haven Android</span> <span class="android-beta-promo-badge" data-i18n="modals.android_beta.badge" style="background:var(--accent-bright,#4caf50)">NOW AVAILABLE</span></h3>
2473+
<span class="android-beta-promo-badge" data-i18n="modals.android_beta.badge" style="background:var(--accent-bright,#4caf50)">NOW AVAILABLE</span>
2474+
<h3 class="android-beta-promo-title"><span data-i18n="modals.android_beta.title">Amni-Haven Android</span></h3>
24682475
<p class="android-beta-promo-subtitle" data-i18n="modals.android_beta.subtitle">A native Android app for Haven, built from the ground up by Amnibro!</p>
24692476
<ul class="android-beta-promo-features">
24702477
<li><span class="promo-check"></span> <span data-i18n="modals.android_beta.feature_native">Native Android experience</span></li>

public/css/style.css

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3389,12 +3389,10 @@ html.rgb-cycling *::after {
33893389
font-weight: 700;
33903390
color: var(--text-primary);
33913391
margin: 0 0 4px;
3392-
display: flex;
3393-
align-items: center;
3394-
justify-content: center;
3395-
gap: 8px;
3392+
text-align: center;
33963393
}
33973394
.android-beta-promo-badge {
3395+
display: inline-block;
33983396
font-size: 10px;
33993397
font-weight: 700;
34003398
text-transform: uppercase;
@@ -3403,6 +3401,7 @@ html.rgb-cycling *::after {
34033401
color: #fff;
34043402
padding: 2px 8px;
34053403
border-radius: 10px;
3404+
margin-bottom: 6px;
34063405
}
34073406
.android-beta-promo-subtitle {
34083407
font-size: 14px;

public/index.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,10 @@ <h1>HAVEN</h1>
178178
<!-- EULA Modal -->
179179
<div class="modal-overlay" id="eula-modal" style="display:none">
180180
<div class="modal eula-modal">
181-
<h3>⚖️ Terms of Service &amp; Release of Liability Agreement</h3>
182-
<div class="eula-content">
181+
<h3>⚖️ Terms of Service &amp; Release of Liability Agreement</h3> <div id="custom-tos-section" style="display:none">
182+
<div class="eula-content" id="custom-tos-content" style="margin-bottom:0;border-bottom:1px solid var(--border,#444);padding-bottom:16px;"></div>
183+
<p style="text-align:center;font-size:12px;color:var(--text-muted,#888);margin:12px 0;">── Default Haven Terms of Service ──</p>
184+
</div> <div class="eula-content">
183185
<p><strong>HAVEN — TERMS OF SERVICE, END USER LICENSE AGREEMENT &amp; RELEASE OF LIABILITY</strong></p>
184186
<p><em>Effective Date: February 12, 2026 &nbsp;|&nbsp; Version 2.0</em></p>
185187

public/js/auth.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@
5050
const titleEl = document.getElementById('server-title');
5151
if (titleEl) titleEl.textContent = d.server_title;
5252
}
53+
if (d.custom_tos) {
54+
const section = document.getElementById('custom-tos-section');
55+
const content = document.getElementById('custom-tos-content');
56+
if (section && content) {
57+
// Render as plain text with paragraph breaks
58+
content.innerHTML = d.custom_tos.split(/\n\n+/).map(p =>
59+
'<p>' + p.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br>') + '</p>'
60+
).join('');
61+
section.style.display = 'block';
62+
}
63+
}
5364
}).catch(() => {});
5465

5566
// ── EULA ─────────────────────────────────────────────

public/js/modules/app-admin.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,11 @@ _snapshotAdminSettings() {
451451
max_emoji_kb: this.serverSettings.max_emoji_kb || '256',
452452
max_poll_options: this.serverSettings.max_poll_options || '10',
453453
update_banner_admin_only: this.serverSettings.update_banner_admin_only || 'false',
454-
default_theme: this.serverSettings.default_theme || ''
454+
default_theme: this.serverSettings.default_theme || '',
455+
custom_tos: this.serverSettings.custom_tos || ''
455456
};
457+
const tosEl = document.getElementById('custom-tos-input');
458+
if (tosEl) tosEl.value = this._adminSnapshot.custom_tos;
456459
// Load webhooks list for admin preview
457460
if (this.user?.isAdmin) {
458461
this.socket.emit('get-webhooks');
@@ -546,6 +549,12 @@ _saveAdminSettings() {
546549
changed = true;
547550
}
548551

552+
const customTos = document.getElementById('custom-tos-input')?.value.trim() || '';
553+
if (customTos !== (snap.custom_tos || '')) {
554+
this.socket.emit('update-server-setting', { key: 'custom_tos', value: customTos });
555+
changed = true;
556+
}
557+
549558
if (changed) {
550559
this._showToast(t('settings.admin.settings_saved'), 'success');
551560
} else {
@@ -583,6 +592,8 @@ _cancelAdminSettings() {
583592
if (uba) uba.checked = snap.update_banner_admin_only === 'true';
584593
const dt = document.getElementById('default-theme-select');
585594
if (dt) dt.value = snap.default_theme || '';
595+
const ct = document.getElementById('custom-tos-input');
596+
if (ct) ct.value = snap.custom_tos || '';
586597
}
587598
document.getElementById('settings-modal').style.display = 'none';
588599
},

public/js/modules/app-messages.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ _renderPinnedPanel(pins) {
679679
list.querySelectorAll('.pinned-item').forEach(item => {
680680
item.addEventListener('click', () => {
681681
const msgId = item.dataset.msgId;
682-
const msgEl = document.querySelector(`[data-msg-id="${msgId}"]`);
682+
const msgEl = document.querySelector(`#messages [data-msg-id="${msgId}"]`);
683683
if (msgEl) {
684684
msgEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
685685
msgEl.classList.add('highlight-flash');

public/js/modules/app-platform.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,12 @@ _initDesktopAppBanner() {
175175
_initAndroidBetaBanner() {
176176
// ── v3 migration: Android app is now a full release; reset dismissals so
177177
// users who dismissed the old closed-beta popup see the new announcement ──
178-
if (!sessionStorage.getItem('_ab_v3_migrated')) {
178+
if (!localStorage.getItem('_ab_v3_migrated')) {
179179
localStorage.removeItem('haven_android_beta_banner_dismissed');
180180
localStorage.removeItem('haven_android_beta_promo_dismissed');
181181
localStorage.removeItem('haven_ab_banner_nodisplay');
182182
localStorage.removeItem('haven_ab_promo_nodisplay');
183-
sessionStorage.setItem('_ab_v3_migrated', '1');
183+
localStorage.setItem('_ab_v3_migrated', '1');
184184
}
185185

186186
// ── Top-bar banner ──

0 commit comments

Comments
 (0)