Skip to content

Commit c693a0c

Browse files
committed
Fix: remove global variables, hightlight tab
1 parent f6e0c4f commit c693a0c

File tree

4 files changed

+177
-47
lines changed

4 files changed

+177
-47
lines changed

lingoanki/static/icon_reduced.png

38.8 KB
Loading

lingoanki/templates/diary.html

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
display: inline-block;
3333
}
3434

35+
nav a.active-tab {
36+
background-color: #b0b0b0; /* Darker grey */
37+
font-weight: bold;
38+
}
39+
3540
textarea {
3641
width: 100%;
3742
height: 300px;
@@ -137,12 +142,12 @@
137142
</div>
138143

139144
<nav>
140-
<a href="/">{{ _('Step 1: Edit Diary') }}</a>
141-
<a href="/diary_html">{{ _('View Diary HTML') }}</a>
142-
<a href="/tprs">{{ _('View TPRS') }}</a>
143-
<a href="/generate_lessons">{{ _('Step 2: Generate Lessons') }}</a>
144-
<a href="/play_audio">{{ _('Step 3: Listen to Lessons') }}</a> <!-- 👈 New link -->
145-
<a href="/output">{{ _('Step 4: Download Output Files') }}</a>
145+
<a href="/" class="{{ 'active-tab' if request.path == '/' else '' }}">{{ _('Step 1: Edit Diary') }}</a>
146+
<a href="/diary_html" class="{{ 'active-tab' if request.path == '/diary_html' else '' }}">{{ _('View Diary HTML') }}</a>
147+
<a href="/tprs" class="{{ 'active-tab' if request.path == '/tprs' else '' }}">{{ _('View TPRS') }}</a>
148+
<a href="/generate_lessons" class="{{ 'active-tab' if request.path == '/generate_lessons' else '' }}">{{ _('Step 2: Generate Lessons') }}</a>
149+
<a href="/play_audio" class="{{ 'active-tab' if request.path == '/play_audio' else '' }}">{{ _('Step 3: Listen to Lessons') }}</a>
150+
<a href="/output" class="{{ 'active-tab' if request.path == '/output' else '' }}">{{ _('Step 4: Download Output Files') }}</a>
146151
</nav>
147152

148153
{% with messages = get_flashed_messages(with_categories=true) %} {% if
Lines changed: 120 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,144 @@
11
<!-- templates/play_audio.html -->
2-
{% extends "diary.html" %} {% block title %}Audio Player{% endblock %} {% block
2+
{% extends "diary.html" %} {% block title %}audio player{% endblock %} {% block
33
content %}
44

5-
<h2>{{ _('Select an MP3 file to play') }}</h2>
5+
<h2>{{ _('select an mp3 file to play') }}</h2>
66

7-
<form id="audioForm" onsubmit="event.preventDefault(); playSelectedFile();">
8-
<label for="file_select">{{ _('Choose an audio file') }}:</label>
7+
<form id="audioform">
8+
<label for="file_select">{{ _('choose an audio file') }}:</label>
99
<select id="file_select" name="file">
1010
{% for mp3_file in mp3_files %}
1111
<option value="{{ mp3_file }}">{{ mp3_file }}</option>
1212
{% endfor %}
1313
</select>
14-
<button type="submit">{{ _('Choose File') }}</button>
14+
<button type="submit">{{ _('choose file') }}</button>
1515
</form>
1616

1717
<script>
18-
function playSelectedFile() {
18+
document.getElementById("audioform").addEventListener("submit", function(event) {
19+
event.preventDefault();
1920
const file = document.getElementById("file_select").value;
20-
window.location.href = "/view_markdown/" + encodeURIComponent(file);
21+
if (file) {
22+
window.location.href = "/view_markdown/" + encodeURIComponent(file);
23+
}
24+
});
25+
</script>
26+
<script>
27+
function playselectedfile() {
28+
const file = document.getelementbyid("file_select").value;
29+
window.location.href = "/view_markdown/" + encodeuricomponent(file);
2130
}
2231
</script>
2332

2433
{% if filename %}
25-
<h3>{{ _('Now Playing') }}: {{ filename }}</h3>
34+
<h3>{{ _('now playing') }}: {{ filename }}</h3>
35+
36+
<!-- Custom Audio Player -->
37+
<div style="display: flex; flex-direction: column; align-items: center; gap: 1rem; max-width: 400px; margin: auto;">
38+
<audio id="audio" preload="metadata">
39+
<source src="{{ url_for('play_audio', filename=filename) }}" type="audio/mp3">
40+
Your browser does not support the audio element.
41+
</audio>
42+
43+
<!-- Time Display -->
44+
<div id="time-display" style="font-family: monospace;">00:00 / 00:00</div>
45+
46+
<!-- Controls -->
47+
<div style="display: flex; align-items: center; gap: 0.5rem; width: 100%;">
48+
<button onclick="seek(-5)">⏪ 5s</button>
49+
<input type="range" id="seekbar" value="0" step="0.1" min="0" max="100" style="flex: 1;">
50+
<button onclick="seek(5)">5s ⏩</button>
51+
</div>
52+
53+
<!-- Play / Pause -->
54+
<button onclick="togglePlay()" id="playpause" style="font-size: 1.5rem;">▶️</button>
55+
</div>
56+
57+
58+
<script>
59+
const audio = document.getElementById('audio');
60+
const seekbar = document.getElementById('seekbar');
61+
const playpause = document.getElementById('playpause');
62+
const timeDisplay = document.getElementById('time-display');
63+
64+
function formatTime(seconds) {
65+
const mins = Math.floor(seconds / 60);
66+
const secs = Math.floor(seconds % 60);
67+
return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
68+
}
69+
70+
audio.addEventListener('loadedmetadata', () => {
71+
timeDisplay.textContent = `00:00 / ${formatTime(audio.duration)}`;
72+
});
73+
74+
audio.addEventListener('timeupdate', () => {
75+
seekbar.value = (audio.currentTime / audio.duration) * 100;
76+
timeDisplay.textContent = `${formatTime(audio.currentTime)} / ${formatTime(audio.duration)}`;
77+
});
2678

27-
<!-- Audio player -->
28-
<audio controls>
29-
<source
30-
src="{{ url_for('play_audio', filename=filename) }}"
31-
type="audio/mp3"
32-
/>
33-
Your browser does not support the audio element.
34-
</audio>
79+
seekbar.addEventListener('input', () => {
80+
audio.currentTime = (seekbar.value / 100) * audio.duration;
81+
});
82+
83+
function seek(seconds) {
84+
audio.currentTime = Math.min(Math.max(audio.currentTime + seconds, 0), audio.duration);
85+
}
86+
87+
function togglePlay() {
88+
if (audio.paused) {
89+
audio.play();
90+
playpause.textContent = '⏸️';
91+
} else {
92+
audio.pause();
93+
playpause.textContent = '▶️';
94+
}
95+
}
96+
97+
// Reset play button on end
98+
audio.addEventListener('ended', () => {
99+
playpause.textContent = '▶️';
100+
});
101+
102+
if ('mediaSession' in navigator) {
103+
navigator.mediaSession.metadata = new MediaMetadata({
104+
title: "{{ filename }}",
105+
artist: "LingoDiary",
106+
album: "Audio Player",
107+
artwork: [
108+
{ src: "/static/icon.ico", sizes: "192x192", type: "image/x-icon" },
109+
{ src: "/static/icon.ico", sizes: "512x512", type: "image/x-icon" }
110+
]
111+
});
112+
113+
navigator.mediaSession.setActionHandler('play', () => {
114+
audio.play();
115+
playpause.textContent = '⏸️';
116+
});
117+
118+
navigator.mediaSession.setActionHandler('pause', () => {
119+
audio.pause();
120+
playpause.textContent = '▶️';
121+
});
122+
123+
navigator.mediaSession.setActionHandler('seekbackward', () => {
124+
seek(-5);
125+
});
126+
127+
navigator.mediaSession.setActionHandler('seekforward', () => {
128+
seek(5);
129+
});
130+
}
131+
132+
133+
</script>
35134

36135
<p>
37136
<a
38137
href="{{ url_for('play_audio', filename=filename) }}"
39138
download="{{ filename }}"
40139
class="btn btn-primary"
41140
>
42-
{{ _('Download this MP3') }}
141+
{{ _('download this mp3') }}
43142
</a>
44143
</p>
45144

@@ -50,15 +149,15 @@ <h3>{{ _('Now Playing') }}: {{ filename }}</h3>
50149
download="{{ md_filename }}"
51150
class="btn btn-secondary"
52151
>
53-
{{ _('Download Markdown') }}
152+
{{ _('download markdown') }}
54153
</a>
55154
</p>
56155
{% endif %}
57156

58-
<!-- Show markdown content if exists -->
157+
<!-- show markdown content if exists -->
59158
{% if content %}
60-
<h3>{{ _('Markdown Content') }}:</h3>
159+
<h3>{{ _('markdown content') }}:</h3>
61160
<div>{{ content|safe }}</div>
62161
{% else %}
63-
<p>No markdown content available for this file.</p>
162+
<p>no markdown content available for this file.</p>
64163
{% endif %} {% endif %} {% endblock %}

0 commit comments

Comments
 (0)