fix(reader): add overflow menu to ebook reader mobile header

This commit is contained in:
ACX
2026-02-11 14:50:49 -07:00
committed by acx10
parent 672b7163f1
commit a9faf7d1ea
3 changed files with 115 additions and 25 deletions

View File

@@ -1,27 +1,53 @@
<div class="reader-header" [class.visible]="isVisible" [style.background]="currentTheme.bg" [style.color]="currentTheme.fg">
<button class="icon-btn" (click)="onShowChapters()" title="Chapters">
<app-reader-icon name="menu" [size]="20"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onCreateBookmark()" [title]="isCurrentCfiBookmarked ? 'Remove Bookmark' : 'Add Bookmark'" [class.active]="isCurrentCfiBookmarked">
<app-reader-icon name="bookmark"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onOpenSearch()" title="Search">
<app-reader-icon name="search"></app-reader-icon>
</button>
<div class="header-left">
<button class="icon-btn" (click)="onShowChapters()" title="Chapters">
<app-reader-icon name="menu" [size]="20"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onCreateBookmark()" [title]="isCurrentCfiBookmarked ? 'Remove Bookmark' : 'Add Bookmark'" [class.active]="isCurrentCfiBookmarked">
<app-reader-icon name="bookmark"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onOpenSearch()" title="Search">
<app-reader-icon name="search"></app-reader-icon>
</button>
</div>
<span class="chapter-title">{{ bookTitle }}</span>
<button class="icon-btn" (click)="onOpenNotes()" title="Notes">
<app-reader-icon name="note"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onToggleFullscreen()" [title]="isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'">
<app-reader-icon [name]="isFullscreen ? 'fullscreen-exit' : 'fullscreen'" [size]="20"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onShowControls()" title="Settings">
<app-reader-icon name="settings"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onShowHelp()" title="Keyboard Shortcuts">
<app-reader-icon name="help" [size]="20"></app-reader-icon>
</button>
<button class="icon-btn" (click)="onClose(); $event.stopPropagation()" title="Close Reader">
<app-reader-icon name="close"></app-reader-icon>
</button>
<div class="header-right">
<button class="icon-btn desktop-only" (click)="onOpenNotes()" title="Notes">
<app-reader-icon name="note"></app-reader-icon>
</button>
<button class="icon-btn desktop-only" (click)="onToggleFullscreen()" [title]="isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'">
<app-reader-icon [name]="isFullscreen ? 'fullscreen-exit' : 'fullscreen'" [size]="20"></app-reader-icon>
</button>
<button class="icon-btn desktop-only" (click)="onShowHelp()" title="Keyboard Shortcuts">
<app-reader-icon name="help" [size]="20"></app-reader-icon>
</button>
<div class="overflow-menu mobile-only">
<button class="icon-btn" (click)="overflowOpen = !overflowOpen; $event.stopPropagation()" title="More">
<app-reader-icon name="dots-vertical" [size]="20"></app-reader-icon>
</button>
@if (overflowOpen) {
<div class="overflow-backdrop" (click)="overflowOpen = false"></div>
<div class="overflow-dropdown" [style.background]="currentTheme.bg" [style.color]="currentTheme.fg">
<button class="overflow-item" (click)="onOpenNotes(); overflowOpen = false">
<app-reader-icon name="note" [size]="18"></app-reader-icon>
<span>Notes</span>
</button>
<button class="overflow-item" (click)="onToggleFullscreen(); overflowOpen = false">
<app-reader-icon [name]="isFullscreen ? 'fullscreen-exit' : 'fullscreen'" [size]="18"></app-reader-icon>
<span>{{ isFullscreen ? 'Exit Fullscreen' : 'Fullscreen' }}</span>
</button>
<button class="overflow-item" (click)="onShowHelp(); overflowOpen = false">
<app-reader-icon name="help" [size]="18"></app-reader-icon>
<span>Keyboard Shortcuts</span>
</button>
</div>
}
</div>
<button class="icon-btn" (click)="onShowControls()" title="Settings">
<app-reader-icon name="settings"></app-reader-icon>
</button>
<button class="icon-btn close-btn" (click)="onClose(); $event.stopPropagation()" title="Close Reader">
<app-reader-icon name="close"></app-reader-icon>
</button>
</div>
</div>

View File

@@ -24,6 +24,13 @@
transform: translateY(0);
}
.header-left,
.header-right {
display: flex;
align-items: center;
z-index: 1;
}
.icon-btn {
background: none;
border: none;
@@ -42,7 +49,7 @@
opacity: 1;
}
&:last-of-type {
&:last-child {
margin-right: 0;
}
@@ -58,6 +65,7 @@
.chapter-title {
flex: 1;
min-width: 0;
text-align: center;
font-size: 14px;
font-weight: 500;
@@ -68,6 +76,53 @@
overflow: hidden;
text-overflow: ellipsis;
min-height: 1.2em;
padding: 0 8px;
}
.mobile-only {
display: none;
}
.overflow-menu {
position: relative;
}
.overflow-backdrop {
position: fixed;
inset: 0;
z-index: 999;
}
.overflow-dropdown {
position: absolute;
top: 100%;
right: 0;
margin-top: 4px;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
z-index: 1000;
min-width: 180px;
padding: 4px;
}
.overflow-item {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
padding: 8px 12px;
background: none;
border: none;
color: inherit;
font-size: 13px;
cursor: pointer;
border-radius: 6px;
white-space: nowrap;
&:hover {
background: rgba(128, 128, 128, 0.15);
}
}
}
@@ -79,5 +134,13 @@
padding: 10px;
margin-right: 2px;
}
.desktop-only {
display: none;
}
.mobile-only {
display: block;
}
}
}

View File

@@ -20,6 +20,7 @@ export class ReaderHeaderComponent implements OnInit, OnDestroy {
isVisible = false;
isCurrentCfiBookmarked = false;
isFullscreen = false;
overflowOpen = false;
get bookTitle(): string {
return this.headerService.title;