Skip to content

Commit

Permalink
Save custom song lyrics in localStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
ashermorgan committed Jul 11, 2024
1 parent 4a8bb37 commit b451043
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 28 deletions.
4 changes: 4 additions & 0 deletions songs2slides/static/create.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ textarea {
.missing summary {
color: var(--error);
}
summary span {
display: none;
}
.missing summary span {
display: inline;
float: right;
font-weight: bold;
}
Expand Down
55 changes: 51 additions & 4 deletions songs2slides/static/create.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
// Global Songs2Slides localStorage prefix
const PREFIX = 's2s'

// HTML form
let form = null

// Page load/reload handler
addEventListener('pageshow', () => {
// Correct page state after returning via browser back button
document.getElementById('post-submit').hidden = true

form = document.getElementById('create-form')

if (STEP === 1) {
// Load songs
for (let row of document.querySelectorAll('tbody tr')) {
Expand All @@ -18,9 +23,10 @@ addEventListener('pageshow', () => {
raw_song.children[1].children[0].value = song.title
raw_song.children[2].children[0].value = song.artist
}
} else if (STEP === 2) {
load_lyrics()
} else if (STEP === 3) {
// Load settings
const form = document.getElementById('create-form')
form['title-slides'].checked = storage_get('title-slides', true)
form['blank-slides'].checked = storage_get('blank-slides', true)
form['output-type'].value = storage_get('output-type', 'html')
Expand All @@ -32,9 +38,10 @@ addEventListener('submit', () => {
// Show loading spinner
document.getElementById('post-submit').hidden = false

if (STEP === 3) {
if (STEP === 2) {
save_lyrics()
} else if (STEP === 3) {
// Save settings
const form = document.getElementById('create-form')
storage_set('title-slides', form['title-slides'].checked)
storage_set('blank-slides', form['blank-slides'].checked)
storage_set('output-type', form['output-type'].value)
Expand Down Expand Up @@ -86,7 +93,47 @@ function save_songs() {
storage_set('songs', songs)
}

// Step 3 helper functions
// Step 2 functions
function get_song_key(title, artist) {
return 'lyrics-' + artist.toLowerCase().replaceAll(' ', '-') +
'-' + title.toLowerCase().replaceAll(' ', '-')
}

function save_lyrics() {
for (let i = 1; `title-${i}` in form; i++) {
const title = form[`title-${i}`].value
const artist = form[`artist-${i}`].value
const lyrics = form[`lyrics-${i}`].value
const key = get_song_key(title, artist)
storage_set(key, lyrics)
}
}

function load_lyrics() {
songs = document.getElementsByTagName('details')
for (let i = 1; `title-${i}` in form; i++) {
const title = form[`title-${i}`].value
const artist = form[`artist-${i}`].value
const key = get_song_key(title, artist)
const saved_lyrics = storage_get(key, '')
if (saved_lyrics !== '') {
form[`lyrics-${i}`].value = saved_lyrics
songs[i - 1].classList.remove('missing')
songs[i - 1].open = false
}
}

// Update missing label
const number = document.getElementsByClassName('missing').length
document.getElementById('missing-count').textContent = number
if (number === 0) {
document.getElementById('missing-message').hidden = true
} else {
document.getElementById('missing-message').hidden = false
}
}

// Local storage helper functions
function storage_get(key, default_value) {
try {
value = JSON.parse(localStorage.getItem(`${PREFIX}.${key}`))
Expand Down
2 changes: 1 addition & 1 deletion songs2slides/templates/create-step-1.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{% endblock head %}

{% block main %}
<form method="POST" action="{{ url_for('.create_step_2') }}">
<form id="create-form" method="POST" action="{{ url_for('.create_step_2') }}">
<h1>Step 1: Select Songs</h1>

<p>
Expand Down
27 changes: 11 additions & 16 deletions songs2slides/templates/create-step-2.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
%}

{% block main %}
<form method="POST" action="{{ url_for('.create_step_3') }}">
<form id="create-form" method="POST" action="{{ url_for('.create_step_3') }}">
<h1>Step 2: Review Lyrics</h1>
<p>
Review the parsed song lyrics below and make any necessary corrections.
Expand All @@ -23,12 +23,10 @@ <h1>Step 2: Review Lyrics</h1>
{{ format_hint }}
</p>

{% if missing > 0 %}
<p>
Lyrics must be entered manually for <strong>{{ missing }}
song{% if missing != 1 %}s{% endif %}</strong>.
<p id="missing-message" {% if missing == 0 %} hidden {% endif %}>
Lyrics must be entered manually for
<span id="missing-count">{{ missing }}</span> song(s).
</p>
{% endif %}

<div>
{% for song in songs %}
Expand All @@ -48,19 +46,16 @@ <h1>Step 2: Review Lyrics</h1>
({{ song.artist }})
{% endif %}

{% if not song.lyrics %}
<span>lyrics not found</span>
{% endif %}
<span {% if not song.lyrics %} hidden {% endif %}>
lyrics not found
</span>
</summary>

{% if song.lyrics %}
<textarea name="lyrics-{{ loop.index }}" placeholder="{{format_hint}}"
aria-label="{{ song.title }} Lyrics">{{ song.lyrics }}</textarea>
{% else %}
<textarea name="lyrics-{{ loop.index }}" placeholder="{{
'Lyrics not found, please enter them here manually.\n\n' +
format_hint }}" aria-label="{{ song.title }} Lyrics"></textarea>
{% endif %}
'Lyrics not found, please enter them here manually.\n\n'
if not songs.lyrics else '' }}{{ format_hint }}"
aria-label="{{ song.title }} Lyrics"
>{{ song.lyrics or '' }}</textarea>
</details>
{% endfor %}
</div>
Expand Down
29 changes: 22 additions & 7 deletions tests/test_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ def test_basic(page: Page):
expect(page).to_have_url('http://localhost:5002/create/step-2/')

# Assert missing song message is correct
expect(page.get_by_text('Lyrics must be entered manually for 1 song.')).to_be_visible()
expect(page.get_by_text('Lyrics must be entered manually for 1 song(s).')).to_be_visible()

# Assert songs are loaded
expect(page.get_by_text('Song 1 (Artist A)')).to_be_visible()
expect(page.get_by_text('Song 1 (Artist A) lyrics not found')).to_be_hidden()
expect(page.get_by_text('lyrics not found').first).to_be_hidden()
expect(page.get_by_text('lyrics not found').last).to_be_visible()
expect(page.get_by_text('Song 5 lyrics not found')).to_be_visible()

# Assert song lyrics are loaded (Song 1 lyrics still collapsed)
Expand Down Expand Up @@ -127,7 +128,9 @@ def test_localStorage(page: Page):
page.get_by_role('button', name='Next').click()
expect(page).to_have_url('http://localhost:5002/create/step-2/')

# Fill in missing lyrics
# Update lyrics
page.get_by_text('Song 1 (Artist A)').click()
page.get_by_role('textbox').first.fill('custom song 1 lyrics')
page.get_by_role('textbox').last.fill('custom song 5 lyrics')

# Click Next
Expand Down Expand Up @@ -166,8 +169,18 @@ def test_localStorage(page: Page):
page.get_by_role('button', name='Next').click()
expect(page).to_have_url('http://localhost:5002/create/step-2/')

# Fill in missing lyrics
page.get_by_role('textbox').last.fill('custom song 5 lyrics')
# Assert song lyrics are collapsed and not missing
expect(page.get_by_role('textbox')).to_have_count(0)
expect(page.get_by_text('lyrics not found').first).to_be_hidden()
expect(page.get_by_text('lyrics not found').last).to_be_hidden()

# Uncollapse songs
page.get_by_text('Song 1 (Artist A)').click()
page.get_by_text('Song 5').click()

# Assert song lyrics are prefilled
expect(page.get_by_role('textbox').first).to_have_value('custom song 1 lyrics')
expect(page.get_by_role('textbox').last).to_have_value('custom song 5 lyrics')

# Click Next
page.get_by_role('button', name='Next').click()
Expand Down Expand Up @@ -231,7 +244,8 @@ def test_back(page: Page):

# Assert songs are loaded
expect(page.get_by_text('Song 1 (Artist A)')).to_be_visible()
expect(page.get_by_text('Song 1 (Artist A) lyrics not found')).to_be_hidden()
expect(page.get_by_text('lyrics not found').first).to_be_hidden()
expect(page.get_by_text('lyrics not found').last).to_be_visible()
expect(page.get_by_text('Song 5 lyrics not found')).to_be_visible()

# Uncollapse Song 1
Expand All @@ -253,8 +267,9 @@ def test_back(page: Page):
page.get_by_role('button', name='Back').click()
expect(page).to_have_url('http://localhost:5002/create/step-2/')

# Uncollapse Song 1
# Uncollapse songs
page.get_by_text('Song 1 (Artist A)').click()
page.get_by_text('Song 5').click()

# Assert bad song lyrics are still loaded
expect(page.get_by_role('textbox')).to_have_count(2)
Expand Down

0 comments on commit b451043

Please sign in to comment.