Starts on suggest page

This commit is contained in:
Effie 2023-06-28 14:34:55 +10:00
parent 1d9ad9d3db
commit 3e3d318134
12 changed files with 239 additions and 17 deletions

66
app.py
View File

@ -1,5 +1,7 @@
import flask
import sqlite3
import csv
import datetime
app = flask.Flask('songbook')
@ -8,7 +10,7 @@ app = flask.Flask('songbook')
# @app.route('/')
# def page():
# db = sqlite3.connect("file:songbook.sqlite?mode=ro", uri=True)
# db = openbook()
# return flask.render_template('.html',
# )
@ -77,6 +79,46 @@ def searchpage():
searchresult=searchresult
)
@app.route('/suggestsearch')
def suggestsearchpage():
db = openbook()
searchargs = flask.request.args['q']
if searchargs:
searchresult = db.execute('''
select
'song', id, name, instr(lower(name),lower(?))
from
song
where
name
like
'%' || ? || '%'
union all
select
'motif', id, name, instr(lower(name),lower(?))
from
motif
where
name
like
'%' || ? || '%'
order by
4
limit
10
''',
(searchargs,)*4
).fetchall()
else:
searchresult = []
return flask.render_template('suggestsearchresults.html',
searchresult=searchresult
)
@ -364,4 +406,24 @@ def songpage(id):
album_info=album_info,
clip_info=clip_info,
artist_info=artist_info
)
)
@app.route('/suggest')
def suggestpage():
return flask.render_template('suggest.html',
)
@app.route('/sent', methods=['POST'])
def sentpage():
with open ('suggestions.csv', 'a', newline='') as suggestlog:
logwriter = csv.writer(suggestlog)
logwriter.writerow([
datetime.datetime.now().isoformat(),
flask.request.form['suggest-description'],
])
return flask.render_template('sent.html',
)

View File

@ -1,13 +1,16 @@
// Check for hash on load.
window.addEventListener('load', (event) => {
const preclicked = window.location.hash.slice(1);
if (! preclicked) return;
const albumheader = document.getElementById(preclicked);
if (albumheader){
albumheader.classList.add('open');
albumheader.scrollIntoView();
}
});
// Scroll to search result album
function albumselect(code){
const albumheader = document.getElementById(code);
for (const other of document.querySelectorAll('.sort-header.album.open')){
@ -18,9 +21,10 @@ function albumselect(code){
document.getElementById('search-results').replaceChildren();
}
// Toggle header when clicked
function albumHeaderClick(clickevent){
const albumheader = clickevent.target;
// console.log(albumheader);
if (albumheader.classList.contains('open')){
albumheader.classList.remove('open');
history.replaceState(null, document.title, `${window.location.origin}${window.location.pathname}${window.location.search}`);
@ -32,4 +36,29 @@ function albumHeaderClick(clickevent){
albumheader.classList.add('open');
window.location.hash = albumheader.id;
}
}
}
// Fill out form with suggest search result
function suggestform1(id, desc){
document.getElementById('connection-1').valueAsNumber = id;
document.getElementById('connection-1-desc').valueAsNumber = desc;
document.getElementById('search-input-suggest-1').value = '';
document.getElementById('search-results-1').replaceChildren();
}
// Mutually exclusive audio playback
function onlyPlayOneIn(container) {
container.addEventListener("play", function(event) {
audio_elements = container.getElementsByTagName("audio")
for(i=0; i < audio_elements.length; i++) {
audio_element = audio_elements[i];
if (audio_element !== event.target) {
audio_element.pause();
}
}
}, true);
}
document.addEventListener("DOMContentLoaded", function() {
onlyPlayOneIn(document.body);
});

View File

@ -226,16 +226,17 @@ header{
/* SEARCH RESULTS */
#search-results{
.search-results{
display: flex; flex-direction: column;
width: 100%;
width: 100%;
cursor: pointer;
}
#search-results h2{
visibility: collapse;
.search-results h2{
display: none;
}
#search-results ul{
.search-results ul{
background-color: var(--search-back);
padding-left: 0;
margin-top: 0;
@ -244,13 +245,13 @@ header{
border-style: solid; border-color: var(--thin-border); border-width: 1px; border-top: 0; border-bottom: 0;
}
#search-results li{
.search-results li{
display: flex; align-items: center;
min-height: 2.4rem;
border-style: solid; border-width: 1px; border-color: var(--thin-border); border-left: 0; border-top: 0; border-right: 0;
}
#search-results a{
.search-results a{
text-decoration: none;
}
@ -277,6 +278,10 @@ header{
min-width: 2.6rem;
}
.search-bar::-webkit-search-cancel-button{
color: var(--text)
}
/* MAIN PAGE */
main{
@ -623,4 +628,40 @@ footer{
.clip-pointer a{
flex-shrink: 1;
}
/* SUGGEST PAGE */
.suggestbox{
display: flex; flex-wrap: wrap; justify-content: center; gap: 4.8rem;
margin-top: 2.4rem;
}
.suggestbox h2{
width: 100%;
text-align: center;
}
.search-items.suggest{
width: 20rem;
}
.suggest-desc{
width: 80%;
}
.suggest-desc textarea{
width: 100%;
}
.suggest-button{
width: 100%;
}
#connection-1{
display: none;
}
#connection-1-desc{
display: none;
}

4
suggestions.csv Normal file
View File

@ -0,0 +1,4 @@
2023-06-27T15:35:08.245616,Testing the form
2023-06-27T15:35:34.195039,testing again
2023-06-27T21:54:35.835288,"Hello from Moss and Nat's
"
1 2023-06-27T15:35:08.245616 Testing the form
2 2023-06-27T15:35:34.195039 testing again
3 2023-06-27T21:54:35.835288 Hello from Moss and Nat's

View File

@ -4,6 +4,7 @@
src = "{{ url_for('static', filename='clip/') }}{{ '%04d' % song_id }}-{{ '%03d' % motif_id }}.flac" type="audio/flac">
</audio>
<span class="clip-pointer">
<img src="{{ url_for('static', filename='motificon.png') }}" alt="Motif Icon" class="connection-icon"/>
<a href = "{{ url_for('motifpage', id=motif_id) }}"> {{ motif }} </a>
</span>

View File

@ -2,7 +2,7 @@
<div class="footer-content">
<span>
Suggest a new connection
<a href="{{ url_for('suggestpage') }}"> Suggest a new connection </a>
</span>
<span>
<a href="#" class="top-of-page">↑Top of page↑</a>

View File

@ -0,0 +1,11 @@
<!-- {% macro icon(type) -%}
<img src="{{ url_for('static', filename='{0}icon.png'.format(type)) }}" alt='{{ type}} icon' class='connection-icon'>
{%- endmacro %}
{% macro link(type) -%}
{{ url_for('{0}page'.format(type), id=) }}"> {{ motif }}
{%- endmacro %}
-->
<!-- {{ icon(type) }}
{{ link(type) }} -->

View File

@ -32,8 +32,8 @@
placeholder="Search..."
hx-get="/search"
hx-trigger="keyup changed delay:500ms, search"
hx-target="#search-results"
hx-target="#search-results-header"
/>
<div id="search-results"></div>
<div id="search-results-header" class="search-results header"></div>
</div>
</div>

10
templates/sent.html Normal file
View File

@ -0,0 +1,10 @@
{% extends "base.html" %}
{% block title %}Suggestion sent{% endblock %}
{% block content %}
{% endblock %}

View File

@ -30,7 +30,7 @@
<!-- Artist info -->
<div class="track-info">
<div class="track-info" >
<div class="songpage-detail">
<h2 >Artist: </h2>
<ul>
@ -75,7 +75,8 @@
<h2>Motifs Featured: </h2>
<ul>
{% for song_id, motif_id, motif in clip_info %}
{% include "songpageclipget.html" %}
{% set type = 'motif' %}
{% include "clipget.html" %}
{% endfor %}
</ul>
</div>

41
templates/suggest.html Normal file
View File

@ -0,0 +1,41 @@
{% extends "base.html" %}
{% block title %}Suggest a connection{% endblock %}
{% block content %}
<p>If you know about a shared motif that you can't find on the website, you can tell me about it here. Just pick the two songs that share a motif - or the motif itself, if it already has a page - and tell me what to listen out for.</p>
<form action="/sent" method="post" >
<div class="suggestbox">
<div class="search-items suggest">
<h2>Song / Motif 1</h2>
<input
id="search-input-suggest-1"
type="search"
name="q"
autocomplete="off"
placeholder="Search..."
hx-get="/suggestsearch"
hx-trigger="keyup changed delay:500ms, search"
hx-target="#search-results-1"
/>
<div id="search-results-1" class="search-results"></div>
</div>
<input type="number" name="connection-1-desc" id="connection-1-desc"/>
<input type="number" name="connection-1" id="connection-1" min="1" max="733"/>
<div class="suggest-desc">
<textarea name="suggest-description">
Suggest a different connection!
</textarea>
</div>
<div class="suggest-button">
<input type="submit" />
</div>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,22 @@
<h2>Search Results:</h2>
<ul>
{% for desc, id, name, _ in searchresult %}
{% if desc == 'song' %}
<li onclick="suggestform('{{ id }}', 1)">
<span class="search-icon">
<img src="{{ url_for('static', filename='songicon.png') }}" alt="Song Icon"/>
</span>
<span class="search-type">Song:</span>
{{ name }}
</li>
{% elif desc == 'motif' %}
<li onclick="suggestform('{{ id }}', 2)">
<span class="search-icon">
<img src="{{ url_for('static', filename='motificon.png') }}" alt="Motif Icon"/>
</span>
<span class="search-type">Motif:</span>
{{ name }}
</li></a>
{% endif %}
{% endfor %}
</ul>