Skip to content

Commit 067f1ae

Browse files
committed
feat(ui): three-level header visibility toggle + read-only pill to bottom-right
1 parent 5024e64 commit 067f1ae

7 files changed

Lines changed: 152 additions & 19 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ TextAgent has undergone significant evolution since its inception. What started
459459

460460
| Date | Commits | Feature / Update |
461461
|------|---------|-----------------:|
462+
| **2026-03-17** | | 🎨 **Three-Level Header & Read-Only Pill** — new three-level header visibility toggle (Full → Compact QAB → fully Hidden with floating "TextAgent" restore pill at top-center, 35% opacity, hover to reveal); header level persists via `localStorage`; "Read-only" shared-view pill repositioned from top-right to bottom-right corner with upward slide-in animation |
462463
| **2026-03-17** | | 🎨 **Shared Banner Auto-Dismiss UX** — green "Viewing shared markdown (read-only)" banner now auto-hides after 4s with smooth slide-up animation; collapses to a floating green "🔒 Read-only" pill in the top-right corner; clicking the editor or pill re-expands the full banner with Edit Copy/Close buttons (auto-hides again after 5s); dynamic `SHARE_BASE_URL` uses `localhost` in dev and `textagent.github.io` in production |
463464
| **2026-03-17** | | 🚀 **AI Worker Limits Upgrade** — raised all task-specific token limits to industry-standard values (e.g. `chat`/`generate`/`markdown` 512→8192, `expand`/`elaborate` 512→4096, `summarize` 256→2048, `autocomplete` 128→512); unified document context limits to 16K/32K chars across Qwen, Gemini, and Common workers; expanded chat history from 10→30 messages with 8x per-message content (500→4000 chars) |
464465
| **2026-03-16** | | 🐛 **Hiragana Quiz & Kana Master Fix** — fixed Hiragana Quiz showing black screen due to double-escaped `</script>` tag preventing script execution; fixed Kana Master hearts (♥) and celebration emoji (🎌) rendering as literal escape sequences instead of Unicode characters |

changelogs/CHANGELOG-header-ui.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Changelog — Header UI & Shared View Pill
2+
3+
## Three-Level Header Visibility Toggle
4+
5+
- Added three-level header visibility system (Full → Compact → Hidden):
6+
- **Level 0 (Full)**: Default — app-header + dropzone visible
7+
- **Level 1 (Compact)**: Quick Action Bar visible, header hidden (existing behavior)
8+
- **Level 2 (Hidden)**: Everything hidden, floating "TextAgent" restore pill at top-center
9+
- Floating restore pill (`header-restore-pill`) appears at 35% opacity, fully visible on hover
10+
- QAB header toggle now transitions from level 1 → 2 (hide everything) instead of restoring full header
11+
- Header level persists across page reloads via `localStorage` (`ta-header-level`)
12+
13+
### Files Modified
14+
- `css/header.css` — added `.header-restore-pill` styles and `body.header-hidden` rules
15+
- `index.html` — added `#header-restore-pill` button element
16+
- `js/app-init.js` — rewired header toggle logic with `setHeaderLevel()` function and localStorage persistence
17+
18+
## Shared View Pill Repositioned to Bottom-Right
19+
20+
- Moved the "Read-only" shared-view pill from top-right to bottom-right corner
21+
- Updated entrance animation direction (`translateY(10px)` instead of `-10px`) for upward slide-in
22+
23+
### Files Modified
24+
- `css/modals.css` — changed `top: 10px; right: 16px``bottom: 10px; right: 16px`
25+
- `styles.css` — same positional change

css/header.css

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,4 +887,56 @@ a:focus {
887887
margin-top: 2px;
888888
padding: 4px;
889889
}
890+
}
891+
892+
/* ========================================
893+
HEADER-HIDDEN STATE (level 2)
894+
======================================== */
895+
896+
body.header-hidden .app-header,
897+
body.header-hidden .quick-action-bar,
898+
body.header-hidden .formatting-toolbar,
899+
body.header-hidden .dropzone {
900+
display: none !important;
901+
}
902+
903+
/* Floating restore pill — small pill at top-center */
904+
.header-restore-pill {
905+
position: fixed;
906+
top: 6px;
907+
left: 50%;
908+
transform: translateX(-50%);
909+
z-index: 999;
910+
display: inline-flex;
911+
align-items: center;
912+
gap: 5px;
913+
padding: 4px 14px;
914+
background-color: var(--header-bg);
915+
color: var(--text-color);
916+
border: 1px solid var(--border-color);
917+
border-radius: 100px;
918+
font-size: 0.82rem;
919+
font-weight: 600;
920+
cursor: pointer;
921+
opacity: 0;
922+
transition: opacity 0.25s ease, transform 0.25s ease, box-shadow 0.2s ease;
923+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
924+
pointer-events: none;
925+
}
926+
927+
/* Show the pill when body has header-hidden class */
928+
body.header-hidden .header-restore-pill {
929+
display: inline-flex !important;
930+
opacity: 0.35;
931+
pointer-events: auto;
932+
}
933+
934+
body.header-hidden .header-restore-pill:hover {
935+
opacity: 1;
936+
transform: translateX(-50%) translateY(1px);
937+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
938+
}
939+
940+
.header-restore-pill i {
941+
font-size: 0.8rem;
890942
}

css/modals.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@
544544
/* --- Shared View Pill (collapsed indicator) --- */
545545
.shared-view-pill {
546546
position: fixed;
547-
top: 10px;
547+
bottom: 10px;
548548
right: 16px;
549549
z-index: 1500;
550550
display: flex;
@@ -559,7 +559,7 @@
559559
cursor: pointer;
560560
box-shadow: 0 2px 12px rgba(26, 127, 55, 0.35);
561561
opacity: 0;
562-
transform: translateY(-10px) scale(0.95);
562+
transform: translateY(10px) scale(0.95);
563563
transition: opacity 0.3s ease, transform 0.3s ease, box-shadow 0.2s ease;
564564
pointer-events: none;
565565
user-select: none;

index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,10 @@ <h5>Menu</h5>
590590

591591
</div>
592592
</div>
593+
<!-- Floating restore pill — visible only when header is fully hidden (level 2) -->
594+
<button id="header-restore-pill" class="header-restore-pill" title="Show full header" style="display:none">
595+
<i class="bi bi-chevron-down"></i> <span class="brand-label">TextAgent</span>
596+
</button>
593597
<!-- Formatting Toolbar -->
594598
<div class="formatting-toolbar" id="formatting-toolbar">
595599
<button class="fmt-btn" data-action="undo" title="Undo (Ctrl+Z)"><i

js/app-init.js

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,76 @@
145145
}
146146

147147
// ========================================
148-
// QUICK ACTION BAR WIRING
148+
// THREE-LEVEL HEADER VISIBILITY TOGGLE
149+
// Level 0 = Full header (app-header + dropzone visible)
150+
// Level 1 = Compact (QAB visible, header hidden)
151+
// Level 2 = Hidden (everything hidden, floating pill only)
149152
// ========================================
150-
if (quickActionBar) {
151-
// Header toggle — restore full header + dropzone view
152-
var qabHeaderToggle = document.getElementById('qab-header-toggle');
153-
if (qabHeaderToggle) qabHeaderToggle.addEventListener('click', function () {
153+
var headerLevel = 0;
154+
var HEADER_LEVEL_KEY = 'ta-header-level';
155+
var restorePill = document.getElementById('header-restore-pill');
156+
157+
function setHeaderLevel(level) {
158+
headerLevel = level;
159+
localStorage.setItem(HEADER_LEVEL_KEY, String(level));
160+
161+
if (level === 0) {
162+
// Full header — show header + dropzone, hide QAB, remove hidden class
163+
document.body.classList.remove('header-hidden');
154164
dropzone.style.display = 'block';
155-
quickActionBar.style.display = 'none';
165+
if (quickActionBar) quickActionBar.style.display = 'none';
156166
if (siteHeader) siteHeader.style.display = '';
157-
});
167+
} else if (level === 1) {
168+
// Compact — hide header + dropzone, show QAB
169+
document.body.classList.remove('header-hidden');
170+
dropzone.style.display = 'none';
171+
if (siteHeader) siteHeader.style.display = 'none';
172+
if (quickActionBar) quickActionBar.style.display = 'flex';
173+
syncQabViewState();
174+
} else if (level === 2) {
175+
// Hidden — hide everything, show floating restore pill
176+
dropzone.style.display = 'none';
177+
if (siteHeader) siteHeader.style.display = 'none';
178+
if (quickActionBar) quickActionBar.style.display = 'none';
179+
document.body.classList.add('header-hidden');
180+
}
181+
}
158182

183+
// Collapse header button (in app-header) — level 0 → 1
184+
var collapseHeaderBtn = document.getElementById('collapse-header-btn');
185+
if (collapseHeaderBtn) collapseHeaderBtn.addEventListener('click', function () {
186+
setHeaderLevel(1);
187+
});
188+
189+
// QAB header toggle — level 1 → 2 (hide everything)
190+
if (quickActionBar) {
191+
var qabHeaderToggle = document.getElementById('qab-header-toggle');
192+
if (qabHeaderToggle) {
193+
// Update title/icon to indicate it will hide everything
194+
qabHeaderToggle.title = 'Hide full header';
195+
var qabIcon = qabHeaderToggle.querySelector('i');
196+
if (qabIcon) qabIcon.className = 'bi bi-chevron-up';
197+
qabHeaderToggle.addEventListener('click', function () {
198+
setHeaderLevel(2);
199+
});
200+
}
201+
}
202+
203+
// Floating restore pill — level 2 → 0 (restore full header)
204+
if (restorePill) restorePill.addEventListener('click', function () {
205+
setHeaderLevel(0);
206+
});
207+
208+
// Restore saved header level on page load
209+
var savedLevel = parseInt(localStorage.getItem(HEADER_LEVEL_KEY), 10);
210+
if (savedLevel === 1 || savedLevel === 2) {
211+
setHeaderLevel(savedLevel);
212+
}
213+
214+
// ========================================
215+
// QUICK ACTION BAR WIRING
216+
// ========================================
217+
if (quickActionBar) {
159218
// New — delegate to existing new-document button
160219
var qabNew = document.getElementById('qab-new');
161220
if (qabNew) qabNew.addEventListener('click', function () {
@@ -351,14 +410,6 @@
351410
});
352411
}
353412

354-
// Collapse header button — hide full header, show QAB
355-
var collapseHeaderBtn = document.getElementById('collapse-header-btn');
356-
if (collapseHeaderBtn) collapseHeaderBtn.addEventListener('click', function () {
357-
dropzone.style.display = 'none';
358-
syncQabVisibility();
359-
syncQabViewState();
360-
});
361-
362413
// ========================================
363414
// GLOBAL KEYBOARD SHORTCUTS
364415
// ========================================

styles.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,7 +2290,7 @@ a:focus {
22902290
/* --- Shared View Pill (collapsed indicator) --- */
22912291
.shared-view-pill {
22922292
position: fixed;
2293-
top: 10px;
2293+
bottom: 10px;
22942294
right: 16px;
22952295
z-index: 1500;
22962296
display: flex;
@@ -2305,7 +2305,7 @@ a:focus {
23052305
cursor: pointer;
23062306
box-shadow: 0 2px 12px rgba(26, 127, 55, 0.35);
23072307
opacity: 0;
2308-
transform: translateY(-10px) scale(0.95);
2308+
transform: translateY(10px) scale(0.95);
23092309
transition: opacity 0.3s ease, transform 0.3s ease, box-shadow 0.2s ease;
23102310
pointer-events: none;
23112311
user-select: none;

0 commit comments

Comments
 (0)