From cf93085e22db560345971a3c8679a2d48b818d0f Mon Sep 17 00:00:00 2001 From: Ashim Kumar Date: Fri, 26 Jun 2026 18:31:45 +0600 Subject: [PATCH] add Audible-style audio player with word-level subtitle highlighting --- doc.py | 2 +- templates/public_home.html | 1334 +++++++++++++++++++++++++++++++++++- 2 files changed, 1326 insertions(+), 10 deletions(-) diff --git a/doc.py b/doc.py index 3a280c5..1eda39f 100644 --- a/doc.py +++ b/doc.py @@ -4,7 +4,7 @@ import mimetypes import markdown # INPUT: Set your Application folder path here -APPLICATION_FOLDER = f'../Audiobook Maker v4.2' # Replace with your actual folder path +APPLICATION_FOLDER = f'../Audiobook Maker v4.3' # Replace with your actual folder path # Add these new variables diff --git a/templates/public_home.html b/templates/public_home.html index 04052d6..985dfe1 100644 --- a/templates/public_home.html +++ b/templates/public_home.html @@ -314,6 +314,311 @@ color: #6b4226; } + /* ============================================ + Book Detail / Share Modal + ============================================= */ + .book-modal-overlay { + position: fixed; + inset: 0; + background: rgba(30, 18, 12, 0.78); + backdrop-filter: blur(6px); + z-index: 1000; + display: none; + align-items: center; + justify-content: center; + padding: 24px; + overflow-y: auto; + } + + .book-modal-overlay.visible { + display: flex; + animation: modalFadeIn 0.25s ease; + } + + @keyframes modalFadeIn { + from { opacity: 0; } + to { opacity: 1; } + } + + .book-modal { + background: #fdf6ea; + border-radius: 18px; + max-width: 440px; + width: 100%; + box-shadow: 0 30px 70px rgba(0,0,0,0.45); + position: relative; + animation: modalSlideUp 0.3s cubic-bezier(0.34, 1.3, 0.64, 1); + border: 1px solid rgba(107, 66, 38, 0.15); + max-height: calc(100vh - 48px); + overflow-y: auto; + } + + @keyframes modalSlideUp { + from { opacity: 0; transform: translateY(24px) scale(0.97); } + to { opacity: 1; transform: translateY(0) scale(1); } + } + + .book-modal-header { + padding: 22px 28px 0; + display: flex; + align-items: center; + justify-content: space-between; + } + + .book-modal-header h3 { + font-family: 'Playfair Display', serif; + font-weight: 700; + font-size: 1.25rem; + color: #4a2c2a; + margin: 0; + text-transform: uppercase; + letter-spacing: 0.5px; + padding-right: 12px; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; + } + + .book-modal-close { + background: rgba(107, 66, 38, 0.1); + border: none; + color: #6b4226; + width: 34px; + height: 34px; + border-radius: 50%; + font-size: 1.1rem; + cursor: pointer; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.2s; + } + + .book-modal-close:hover { background: rgba(107, 66, 38, 0.22); } + + .book-modal-body { + padding: 18px 28px 28px; + } + + .book-modal-top { + display: flex; + gap: 18px; + margin-bottom: 22px; + } + + .book-modal-cover { + width: 96px; + height: 144px; + flex-shrink: 0; + border-radius: 4px 8px 8px 4px; + overflow: hidden; + box-shadow: 4px 6px 16px rgba(0,0,0,0.25); + background: linear-gradient(135deg, #2c3e50, #4a6278); + position: relative; + display: flex; + flex-direction: column; + justify-content: flex-end; + padding: 10px; + color: white; + } + + .book-modal-cover img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + } + + .book-modal-cover .cover-overlay { + position: absolute; + inset: 0; + background: linear-gradient(to bottom, transparent 40%, rgba(0,0,0,0.85)); + } + + .book-modal-cover-text { + position: relative; + z-index: 2; + font-family: 'Playfair Display', serif; + font-size: 0.72rem; + font-weight: 700; + line-height: 1.2; + text-shadow: 0 1px 3px rgba(0,0,0,0.6); + } + + .book-modal-info { + flex: 1; + min-width: 0; + } + + .book-modal-info .bm-title { + font-family: 'Playfair Display', serif; + font-weight: 700; + font-size: 1.3rem; + color: #2c1810; + line-height: 1.2; + margin-bottom: 6px; + } + + .book-modal-info .bm-meta { + font-size: 0.82rem; + color: #6b4226; + margin-bottom: 4px; + display: flex; + align-items: center; + gap: 6px; + flex-wrap: wrap; + } + + .book-modal-info .bm-meta i { opacity: 0.7; } + + .book-modal-info .bm-desc { + font-size: 0.85rem; + color: #5a4636; + line-height: 1.5; + margin-top: 8px; + } + + .book-modal-actions { + display: flex; + gap: 10px; + margin-bottom: 22px; + } + + .btn-read { + flex: 0 0 auto; + background: linear-gradient(135deg, #c0392b, #a93226); + color: white; + border: none; + padding: 11px 26px; + border-radius: 10px; + font-weight: 700; + font-size: 0.92rem; + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + text-decoration: none; + transition: all 0.2s; + box-shadow: 0 4px 12px rgba(192, 57, 43, 0.35); + } + + .btn-read:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(192, 57, 43, 0.45); + color: white; + } + + .btn-copy-link { + flex: 1; + background: rgba(107, 66, 38, 0.1); + color: #6b4226; + border: 1.5px solid rgba(107, 66, 38, 0.25); + padding: 11px 18px; + border-radius: 10px; + font-weight: 600; + font-size: 0.88rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + transition: all 0.2s; + } + + .btn-copy-link:hover { background: rgba(107, 66, 38, 0.18); } + .btn-copy-link.copied { + background: #2e7d32; + color: white; + border-color: #2e7d32; + } + + .share-section-label { + font-size: 0.78rem; + font-weight: 700; + color: #6b4226; + text-transform: uppercase; + letter-spacing: 0.6px; + margin-bottom: 12px; + display: flex; + align-items: center; + gap: 6px; + } + + .share-buttons { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 24px; + } + + .share-btn { + border: none; + color: white; + padding: 8px 14px; + border-radius: 8px; + font-weight: 600; + font-size: 0.8rem; + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; + text-decoration: none; + transition: all 0.2s; + } + + .share-btn:hover { transform: translateY(-2px); filter: brightness(1.08); color: white; } + .share-btn i { font-size: 0.95rem; } + + .share-facebook { background: #1877f2; } + .share-twitter { background: #000000; } + .share-pinterest{ background: #e60023; } + .share-whatsapp { background: #25d366; } + .share-linkedin { background: #0a66c2; } + .share-email { background: #6b4226; } + + .qr-section { + display: flex; + align-items: center; + gap: 16px; + padding: 16px; + background: rgba(107, 66, 38, 0.06); + border-radius: 12px; + border: 1px solid rgba(107, 66, 38, 0.12); + } + + .qr-code-box { + width: 110px; + height: 110px; + flex-shrink: 0; + background: white; + border-radius: 8px; + padding: 7px; + display: flex; + align-items: center; + justify-content: center; + } + + .qr-code-box img, .qr-code-box canvas { + width: 100% !important; + height: 100% !important; + } + + .qr-text { + font-size: 0.85rem; + color: #5a4636; + line-height: 1.5; + } + + .qr-text strong { + color: #4a2c2a; + display: block; + margin-bottom: 2px; + font-size: 0.9rem; + } + /* Responsive */ @media (max-width: 768px) { .header-container { @@ -343,6 +648,9 @@ .bookcase { padding: 16px; } + + .book-modal-actions { flex-wrap: wrap; } + .qr-section { flex-direction: column; text-align: center; } } @media (max-width: 480px) { @@ -354,6 +662,279 @@ .book-author { font-size: 0.7rem; } } + /* ============================================ + Audiobook Player Overlay (Audible-style) + ============================================= */ + .player-overlay { + position: fixed; + inset: 0; + background: rgba(20, 12, 8, 0.92); + backdrop-filter: blur(10px); + z-index: 1200; + display: none; + align-items: center; + justify-content: center; + padding: 20px; + } + .player-overlay.visible { + display: flex; + animation: modalFadeIn 0.25s ease; + } + .player-card { + background: #fdf6ea; + border-radius: 20px; + width: 100%; + max-width: 460px; + max-height: calc(100vh - 40px); + display: flex; + flex-direction: column; + box-shadow: 0 30px 70px rgba(0,0,0,0.5); + overflow: hidden; + animation: modalSlideUp 0.3s cubic-bezier(0.34, 1.3, 0.64, 1); + } + .player-top-bar { + display: flex; + align-items: center; + justify-content: space-between; + padding: 14px 18px; + flex-shrink: 0; + } + .player-top-bar .pt-logo { + color: #c0392b; + font-size: 1.4rem; + } + .player-close { + background: rgba(107, 66, 38, 0.1); + border: none; + color: #6b4226; + width: 34px; + height: 34px; + border-radius: 50%; + font-size: 1.05rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.2s; + } + .player-close:hover { background: rgba(107, 66, 38, 0.22); } + + .player-body { + padding: 0 24px 20px; + overflow-y: auto; + flex: 1; + display: flex; + flex-direction: column; + } + + .player-cover { + width: 180px; + height: 180px; + margin: 0 auto 18px; + border-radius: 12px; + overflow: hidden; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); + background: linear-gradient(135deg, #2c3e50, #4a6278); + position: relative; + display: flex; + align-items: flex-end; + padding: 14px; + color: white; + flex-shrink: 0; + } + .player-cover img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + } + .player-cover .cover-overlay { + position: absolute; + inset: 0; + background: linear-gradient(to bottom, transparent 45%, rgba(0,0,0,0.8)); + } + .player-cover-text { + position: relative; + z-index: 2; + font-family: 'Playfair Display', serif; + font-weight: 700; + font-size: 0.95rem; + line-height: 1.2; + text-shadow: 0 2px 4px rgba(0,0,0,0.6); + } + + .player-book-title { + text-align: center; + font-family: 'Playfair Display', serif; + font-weight: 700; + font-size: 1.15rem; + color: #2c1810; + margin-bottom: 2px; + } + .player-book-author { + text-align: center; + font-size: 0.82rem; + color: #6b4226; + font-style: italic; + margin-bottom: 14px; + } + + /* Subtitle box with word highlight */ + .player-subtitle { + background: rgba(107, 66, 38, 0.07); + border: 1px solid rgba(107, 66, 38, 0.14); + border-radius: 12px; + padding: 16px 18px; + font-size: 1.05rem; + line-height: 1.7; + color: #3e2b1d; + max-height: 160px; + overflow-y: auto; + margin-bottom: 16px; + min-height: 70px; + } + .player-subtitle .pw { + cursor: pointer; + border-radius: 3px; + transition: background 0.15s, color 0.15s; + } + .player-subtitle .pw:hover { background: #f0e2cd; } + .player-subtitle .pw.current-word { + color: #c0392b; + font-weight: 700; + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: 3px; + } + .player-subtitle .pw.current-sentence { + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + background-color: #f3e3c8; + border-radius: 4px; + } + .player-subtitle-empty { + color: #a08a72; + font-style: italic; + text-align: center; + } + + .player-section-label { + text-align: center; + font-size: 0.78rem; + color: #8a6d52; + margin-bottom: 10px; + font-weight: 500; + } + .player-section-label strong { color: #4a2c2a; } + + /* Seek bar */ + .player-seek { + width: 100%; + -webkit-appearance: none; + appearance: none; + height: 6px; + border-radius: 3px; + background: rgba(107, 66, 38, 0.2); + cursor: pointer; + margin-bottom: 6px; + } + .player-seek::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 16px; + height: 16px; + border-radius: 50%; + background: #c0392b; + cursor: pointer; + box-shadow: 0 1px 4px rgba(0,0,0,0.3); + } + .player-seek::-moz-range-thumb { + width: 16px; + height: 16px; + border: none; + border-radius: 50%; + background: #c0392b; + cursor: pointer; + } + .player-time-row { + display: flex; + justify-content: space-between; + font-size: 0.72rem; + color: #8a6d52; + margin-bottom: 14px; + font-variant-numeric: tabular-nums; + } + + /* Controls */ + .player-controls { + display: flex; + align-items: center; + justify-content: center; + gap: 22px; + margin-bottom: 6px; + } + .player-ctrl-btn { + background: none; + border: none; + color: #4a2c2a; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: transform 0.15s, opacity 0.2s; + } + .player-ctrl-btn:hover { transform: scale(1.12); } + .player-ctrl-btn:active { transform: scale(0.95); } + .player-ctrl-btn:disabled { opacity: 0.3; cursor: not-allowed; transform: none; } + .player-ctrl-btn svg { width: 30px; height: 30px; fill: currentColor; } + .player-ctrl-btn .label { + font-size: 0.62rem; + font-weight: 700; + } + + .player-play-btn { + width: 66px; + height: 66px; + border-radius: 50%; + background: linear-gradient(135deg, #c0392b, #a93226); + color: white; + border: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 6px 18px rgba(192, 57, 43, 0.4); + transition: transform 0.15s; + position: relative; + } + .player-play-btn:hover { transform: scale(1.06); } + .player-play-btn:active { transform: scale(0.96); } + .player-play-btn svg { width: 32px; height: 32px; fill: white; } + .player-play-spinner { + width: 30px; height: 30px; + border: 3px solid rgba(255,255,255,0.35); + border-top-color: white; + border-radius: 50%; + animation: spin 0.8s linear infinite; + display: none; + } + .player-play-btn.loading svg { display: none; } + .player-play-btn.loading .player-play-spinner { display: block; } + @keyframes spin { to { transform: rotate(360deg); } } + + .player-counter { + text-align: center; + font-size: 0.72rem; + color: #a08a72; + margin-top: 10px; + } + + @media (max-width: 480px) { + .player-cover { width: 150px; height: 150px; } + .player-controls { gap: 16px; } + } + /* Footer */ .library-footer { text-align: center; @@ -403,8 +984,106 @@

Powered by Audiobook Maker Pro v4.2

+ +
+
+
+

Book

+ +
+
+
+
+
+
+
+
+
+
+
+ +
+ + Read + + + +
+ + + + +
+
+
+ Scan to open + Open this audiobook on any device by scanning the QR code. +
+
+
+
+
+ + +
+
+
+ + +
+
+
+
+
+ + + +
+
Press play to begin listening.
+
+ + +
+ 00:00 + 00:00 +
+ +
+ + + +
+ +
+
+
+
+ + +