TTS-Arena / app /ui.py
mrfakename's picture
Autoplay, keyboard shortcuts
6e03e6f
import gradio as gr
from .config import *
from .messages import *
from .ui_vote import *
from .ui_battle import *
from .ui_leaderboard import *
with gr.Blocks() as about:
with gr.Row():
with gr.Accordion("News", open=False):
gr.Markdown(NEWS)
gr.Markdown(ABOUT)
CSS = """
footer {visibility: hidden}
textbox {resize: none}
/* Custom scrollbar styles */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: var(--background-fill-primary);
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: var(--border-color-primary);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--body-text-color);
}
"""
with gr.Blocks(css=CSS + """
/* Modal styles */
.shortcuts-modal {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--background-fill-primary);
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
z-index: 1000;
max-width: 500px;
width: 90%;
}
.shortcuts-modal.show {
display: block;
}
.modal-backdrop {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(10px);
z-index: 999;
}
.modal-backdrop.show {
display: block;
}
.close-button {
position: absolute;
top: 10px;
right: 10px;
background: none;
border: none;
font-size: 20px;
cursor: pointer;
color: var(--body-text-color);
}
.close-button:hover {
color: var(--error-text-color);
}
""", theme=gr.themes.Default(font=[gr.themes.GoogleFont("Geist"), "sans-serif"]), title="TTS Arena") as app:
gr.Markdown(DESCR)
gr.TabbedInterface([vote, battle, leaderboard, about], ['Vote', 'Battle', 'Leaderboard', 'About'])
if CITATION_TEXT:
with gr.Row():
with gr.Accordion("Citation", open=False):
gr.Markdown(f"If you use this data in your publication, please cite us!\n\nCopy the BibTeX citation to cite this source:\n\n```bibtext\n{CITATION_TEXT}\n```\n\nPlease note that all generated audio clips should be assumed unsuitable for redistribution or commercial use.")
# Add modal HTML
gr.HTML("""
<div class="modal-backdrop"></div>
<div class="shortcuts-modal">
<button class="close-button" onclick="toggleModal(false)">×</button>
<h3>Keyboard Shortcuts</h3>
<p><strong>Global:</strong></p>
<ul>
<li><code>?</code> or <code>Shift + /</code> - Show this help dialog</li>
<li><code>Esc</code> - Close this dialog</li>
</ul>
<p><strong>Vote & Battle Mode:</strong></p>
<ul>
<li><code>r</code> - Generate random text</li>
<li><code>Ctrl/Cmd + Enter</code> - Synthesize text</li>
<li><code>a</code> - Vote for option A</li>
<li><code>b</code> - Vote for option B</li>
</ul>
</div>
""")
# Add modal control JavaScript
app.load(None, None, js="""
function() {
function toggleModal(show) {
document.querySelector('.shortcuts-modal').classList.toggle('show', show);
document.querySelector('.modal-backdrop').classList.toggle('show', show);
}
document.addEventListener('keydown', function(e) {
// Only handle shortcuts when not typing in an input
if (document.activeElement.tagName === 'INPUT' ||
document.activeElement.tagName === 'TEXTAREA') {
return;
}
// Check for shift + / or ? key
if ((e.key === '/' && e.shiftKey) || e.key === '?') {
toggleModal(true);
}
// Check for escape key
else if (e.key === 'Escape') {
toggleModal(false);
}
});
// Close modal when clicking backdrop
document.querySelector('.modal-backdrop').addEventListener('click', function() {
toggleModal(false);
});
// Make toggleModal available globally
window.toggleModal = toggleModal;
}
""")