commit 2d7e234b8f3a2b67b285db5703bf1b8de0f4a6b9
parent e5a1478fceb3b5e2f72fee32c070db0be9560807
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Tue, 26 Mar 2024 11:45:43 -0700
Combine create steps into one template
Diffstat:
7 files changed, 196 insertions(+), 166 deletions(-)
diff --git a/songs2slides/routes.py b/songs2slides/routes.py
@@ -41,7 +41,7 @@ def home():
@bp.get('/create/')
def create():
- return render_template('create-step-1.html')
+ return render_template('create.html', step=1, songs=[], missing=0)
@bp.post('/create/')
def get_lyrics():
@@ -61,7 +61,7 @@ def get_lyrics():
missing = sum([1 for x in songs if x.lyrics == None])
# Return song data
- return render_template('create-step-2.html', songs=songs, missing=missing)
+ return render_template('create.html', step=2, songs=songs, missing=missing)
@bp.post('/slides/')
def create_slides():
diff --git a/songs2slides/static/create.css b/songs2slides/static/create.css
@@ -66,7 +66,7 @@ textarea {
resize: vertical;
}
-.missing {
+.missing summary {
color: red;
}
.missing summary span {
diff --git a/songs2slides/static/create.js b/songs2slides/static/create.js
@@ -1,10 +1,11 @@
-addEventListener("submit", () => {
- if (document.querySelector('input[value=html]:checked]') === null) {
- // Don't show #after-submit for HTML slide creation
- document.getElementById('after-submit').hidden = false
- }
- if (document.getElementById('step-2')) {
+addEventListener('submit', () => {
+ if (document.getElementById('step-1').hidden == false) {
+ // Show step 1 spinner
+ document.getElementById('post-step-1').hidden = false
+ } else if (document.querySelector('input[value=pptx]').checked) {
+ // Show step 2 downloading message
document.getElementById('step-2').hidden = true
+ document.getElementById('post-step-2').hidden = false
}
});
@@ -30,3 +31,11 @@ function renumber_songs() {
songs[i].children[3].children[0].onclick = () => remove_song(i)
}
}
+
+/* step 2 functions */
+function back() {
+ document.getElementById('step-1').hidden = false
+ document.getElementById('post-step-1').hidden = true
+ document.getElementById('step-2').hidden = true
+ document.getElementById('post-step-2').hidden = true
+}
diff --git a/songs2slides/templates/create-step-1.html b/songs2slides/templates/create-step-1.html
@@ -1,70 +0,0 @@
-{% extends "layout.html" %}
-
-{% block head %}
-<link rel="stylesheet" href="{{ url_for('static', filename='create.css') }}"/>
-<script src="{{ url_for('static', filename='create.js') }}"></script>
-{% endblock head %}
-
-{% block main %}
-<form id="step-1" method="POST">
- <h1>Step 1: Select Songs</h1>
-
- <p>
- Select the songs to include in the slide show by their title and artist.
- </p>
-
- <template id="row-template">
- <tr>
- <td>.</td>
- <td>
- <input name="title-" placeholder="Song title" required/>
- </td>
- <td>
- <input name="artist-" placeholder="Song artist"/>
- </td>
- <td>
- <input type="button" value="Remove"/>
- </td>
- </tr>
- </template>
-
- <table>
- <thead>
- <tr>
- <th></th>
- <th>Title</th>
- <th>Artist</th>
- <th></th>
- </tr>
- </thead>
- <tbody id="songs">
- <tr>
- <td>1.</td>
- <td>
- <input type="text" name="title-1" placeholder="Song title" required/>
- </td>
- <td>
- <input type="text" name="artist-1" placeholder="Song artist"/>
- </td>
- <td>
- <input type="button" value="Remove" onclick="remove_song(1)"/>
- </td>
- </tr>
- </tbody>
- </table>
-
- <div id="actions">
- <input type="button" value="Add song" onclick="add_song()"/>
- <button>
- Next
- </button>
- </div>
-</form>
-
-<div id="after-submit" class="loading-modal" hidden>
- <div>
- <p>Loading your song lyrics...</p>
- <div class="spinner"></div>
- </div>
-</div>
-{% endblock main %}
diff --git a/songs2slides/templates/create-step-2.html b/songs2slides/templates/create-step-2.html
@@ -1,85 +0,0 @@
-{% extends "layout.html" %}
-
-{% block head %}
-<link rel="stylesheet" href="{{ url_for('static', filename='create.css') }}"/>
-<script src="{{ url_for('static', filename='create.js') }}"></script>
-{% endblock head %}
-
-{% block main %}
-<form id="step-2" method="POST" action="{{ url_for('.create_slides') }}">
- <h1>Step 2: Preview Slides</h1>
- <p>
- Review the parsed song lyrics below and make any necessary corrections.
- One blank line represents the start of a new slide and three blank
- lines represent an empty slide.
- </p>
-
- {% if missing > 0 %}
- <p class="missing">
- Lyrics must be entered manually for {{ missing }}
- {% if missing == 1 %} song. {% else %} songs. {% endif %}
- </p>
- {% endif %}
-
- <div id="song-lyrics">
- {% for song in songs %}
- <details {% if not song.lyrics %} open class="missing" {% endif %} >
- <input hidden name="title-{{ loop.index }}"
- value="{{ song.title }}"/>
- <input hidden name="artist-{{ loop.index }}"
- value="{{ song.artist }}"/>
-
- <summary>
- <i>{{ song.title }}</i>
-
- {% if song.artist %}
- ({{ song.artist }})
- {% endif %}
-
- {% if not song.lyrics %}
- <span>lyrics not found</span>
- {% endif %}
- </summary>
-
- {% if song.lyrics %}
- <textarea name="lyrics-{{ loop.index }}">{{ song.lyrics }}</textarea>
- {% else %}
- <textarea name="lyrics-{{ loop.index }}" placeholder="{{
- 'Lyrics not found, please enter them here manually.\n\nOne ' +
- 'blank line represents the start of a new slide and three ' +
- 'blank lines represent an empty slide.'}}"></textarea>
- {% endif %}
- </details>
- {% endfor %}
- </div>
-
- <fieldset>
- <legend>Output type:</legend>
- <label>
- <input type="radio" name="output-type" value="pptx" checked/>
- PowerPoint Download
- </label>
- <label>
- <input type="radio" name="output-type" value="html"/>
- Online View
- </label>
- </fieldset>
-
- <div id="actions">
- <a href="{{ url_for('.create') }}">Back</a>
- <button>
- Create Slide Show
- </button>
- </div>
-</form>
-
-<div id="after-submit" hidden>
- <p>
- Your slide show is being downloaded,
- thank you for using Songs2Slides.
- </p>
- <p>
- <a href="{{ url_for('.create') }}">Create another slide show</a>
- </p>
-</div>
-{% endblock main %}
diff --git a/songs2slides/templates/create.html b/songs2slides/templates/create.html
@@ -0,0 +1,176 @@
+{% extends "layout.html" %}
+
+{% block head %}
+<link rel="stylesheet" href="{{ url_for('static', filename='create.css') }}"/>
+<script src="{{ url_for('static', filename='create.js') }}"></script>
+{% endblock head %}
+
+{% block main %}
+<form id="step-1" method="POST" {% if step == 2 %} hidden {% endif %}>
+ <h1>Step 1: Select Songs</h1>
+
+ <p>
+ Select the songs to include in the slide show by their title and artist.
+ </p>
+
+ <template id="row-template">
+ <tr>
+ <td></td>
+ <td>
+ <input name="title-" placeholder="Song title" required/>
+ </td>
+ <td>
+ <input name="artist-" placeholder="Song artist"/>
+ </td>
+ <td>
+ <input type="button" value="Remove"/>
+ </td>
+ </tr>
+ </template>
+
+ <table>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Title</th>
+ <th>Artist</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody id="songs">
+ {% if step == 1 %}
+ <tr>
+ <td>1.</td>
+ <td>
+ <input type="text" name="title-1" placeholder="Song title" required/>
+ </td>
+ <td>
+ <input type="text" name="artist-1" placeholder="Song artist"/>
+ </td>
+ <td>
+ <input type="button" value="Remove" onclick="remove_song(1)"/>
+ </td>
+ </tr>
+ {% else %}
+ {% for song in songs %}
+ <tr>
+ <td>{{ loop.index }}.</td>
+ <td>
+ <input type="text" name="title-{{ loop.index }}" required
+ placeholder="Song title" value="{{ song.title }}"/>
+ </td>
+ <td>
+ <input type="text" name="artist-{{ loop.index }}"
+ placeholder="Song artist" value="{{ song.artist }}"/>
+ </td>
+ <td>
+ <input type="button" value="Remove"
+ onclick="remove_song({{ loop.index }})"/>
+ </td>
+ </tr>
+ {% endfor %}
+ {% endif %}
+ </tbody>
+ </table>
+
+ <div id="actions">
+ <input type="button" value="Add song" onclick="add_song()"/>
+ <button>
+ Next
+ </button>
+ </div>
+</form>
+
+<div id="post-step-1" class="loading-modal" hidden>
+ <div>
+ <p>Loading your song lyrics...</p>
+ <div class="spinner"></div>
+ </div>
+</div>
+
+<form id="step-2" method="POST" {% if step == 1 %} hidden {% endif %}
+ action="{{ url_for('.create_slides') }}">
+
+ {% set format_hint =
+ 'One blank line represents the start of a new slide and three blank ' +
+ 'lines represent an empty slide.'
+ %}
+
+ <h1>Step 2: Preview Slides</h1>
+ <p>
+ Review the parsed song lyrics below and make any necessary corrections.
+ {{ format_hint }}
+ </p>
+
+ {% if missing > 0 %}
+ <p>
+ Lyrics must be entered manually for
+ {{ missing }} {% if missing == 1 %} song. {% else %} songs. {% endif %}
+ </p>
+ {% endif %}
+
+ <div>
+ {% for song in songs %}
+ <details
+ {% if missing == 0 and loop.index == 1 %} open {% endif %}
+ {% if not song.lyrics %} open class="missing" {% endif %}>
+
+ <input hidden name="title-{{ loop.index }}"
+ value="{{ song.title }}"/>
+ <input hidden name="artist-{{ loop.index }}"
+ value="{{ song.artist }}"/>
+
+ <summary>
+ <i>{{ song.title }}</i>
+
+ {% if song.artist %}
+ ({{ song.artist }})
+ {% endif %}
+
+ {% if not song.lyrics %}
+ <span>lyrics not found</span>
+ {% endif %}
+ </summary>
+
+ {% if song.lyrics %}
+ <textarea name="lyrics-{{ loop.index }}"
+ placeholder="{{format_hint}}">{{ song.lyrics }}</textarea>
+ {% else %}
+ <textarea name="lyrics-{{ loop.index }}" placeholder="{{
+ 'Lyrics not found, please enter them here manually.\n\n' +
+ format_hint }}"></textarea>
+ {% endif %}
+ </details>
+ {% endfor %}
+ </div>
+
+ <fieldset>
+ <legend>Output type:</legend>
+ <label>
+ <input type="radio" name="output-type" value="pptx" checked/>
+ PowerPoint Download
+ </label>
+ <label>
+ <input type="radio" name="output-type" value="html"/>
+ Online View
+ </label>
+ </fieldset>
+
+ <div id="actions">
+ <input onclick="back()" type="button" value="Back"/>
+ <button>
+ Create Slide Show
+ </button>
+ </div>
+</form>
+
+<div id="post-step-2" hidden>
+ <p>
+ Your slide show is being downloaded,
+ thank you for using Songs2Slides.
+ </p>
+ <p>
+ <a href="{{ url_for('.create') }}">Create another slide show</a>
+ </p>
+</div>
+{% endblock main %}
diff --git a/tests/test_routes.py b/tests/test_routes.py
@@ -32,7 +32,7 @@ class TestRoutes(unittest.TestCase):
# Assert mocks called correctly
mocked_get.assert_has_calls([call('T1', 'A1'), call('T2', 'A2')])
mocked_parse.assert_has_calls([call('L1', 4), call('L2', 4)])
- mocked_render.assert_called_with('create-step-2.html', songs=songs, missing=0)
+ mocked_render.assert_called_with('create.html', step=2, songs=songs, missing=0)
def test_get_lyrics_one_error(self):
with patch('songs2slides.core.get_song_data') as mocked_get, \
@@ -58,7 +58,7 @@ class TestRoutes(unittest.TestCase):
# Assert mocks called correctly
mocked_get.assert_has_calls([call('T1', 'A1'), call('T2', 'A2')])
mocked_parse.assert_has_calls([call('L2', 4)])
- mocked_render.assert_called_with('create-step-2.html', songs=songs, missing=1)
+ mocked_render.assert_called_with('create.html', step=2, songs=songs, missing=1)
def test_get_lyrics_missing_artist(self):
with patch('songs2slides.core.get_song_data') as mocked_get: