]> littlesong.place Git - littlesongplace.git/commitdiff
Visual updates, update news
authorChris Fulljames <christianfulljames@gmail.com>
Sat, 26 Apr 2025 17:02:25 +0000 (13:02 -0400)
committerChris Fulljames <christianfulljames@gmail.com>
Sat, 26 Apr 2025 17:02:25 +0000 (13:02 -0400)
28 files changed:
src/littlesongplace/colors.py
src/littlesongplace/songs.py
src/littlesongplace/static/MatSaleh.otf [new file with mode: 0644]
src/littlesongplace/static/Unageo-ExtraBold-Italic.ttf [new file with mode: 0644]
src/littlesongplace/static/Unageo-ExtraBold.ttf [new file with mode: 0644]
src/littlesongplace/static/Unageo-Medium-Italic.ttf [new file with mode: 0644]
src/littlesongplace/static/Unageo-Medium.ttf [new file with mode: 0644]
src/littlesongplace/static/nav.js
src/littlesongplace/static/player.js
src/littlesongplace/static/styles.css
src/littlesongplace/templates/about.html
src/littlesongplace/templates/activity.html
src/littlesongplace/templates/base.html
src/littlesongplace/templates/comment.html
src/littlesongplace/templates/index.html
src/littlesongplace/templates/jam-event-list.html
src/littlesongplace/templates/jam-event.html
src/littlesongplace/templates/jam.html
src/littlesongplace/templates/jams-main.html
src/littlesongplace/templates/login.html
src/littlesongplace/templates/news.html
src/littlesongplace/templates/profile.html
src/littlesongplace/templates/signup.html
src/littlesongplace/templates/song-list.html
src/littlesongplace/templates/songs-by-tag.html
src/littlesongplace/users.py
test/test_auth.py
test/test_jams.py

index b10a857d96a39edcd2243d8d78ae40c676f5064c..c2202c51cc78b3349408a46f2f9cddc3d50cb4bd 100644 (file)
@@ -1,5 +1,5 @@
 BGCOLOR = "#e8e6b5"
-FGCOLOR = "#695c73"
-ACCOLOR = "#9373a9"
+FGCOLOR = "#514659"
+ACCOLOR = "#b36fab"
 DEFAULT_COLORS = dict(bgcolor=BGCOLOR, fgcolor=FGCOLOR, accolor=ACCOLOR)
 
index 110643cf1474c5e931cb3ec104ed5c02af15a641..a8c25f8c5a20e094291467bd0e30cac41e22c559 100644 (file)
@@ -23,6 +23,7 @@ bp = Blueprint("songs", __name__)
 class Song:
     songid: int
     userid: int
+    user: users.User
     threadid: int
     username: str
     title: str
@@ -37,7 +38,8 @@ class Song:
     event_title: Optional[str]
 
     def json(self):
-        return json.dumps(vars(self))
+        vs = vars(self)
+        return json.dumps({k: vs[k] for k in vs if not isinstance(vs[k], users.User)})
 
     def get_comments(self):
         return comments.for_thread(self.threadid)
@@ -204,6 +206,7 @@ def _from_db(query, args=()):
         songs.append(Song(
             songid=sd["songid"],
             userid=sd["userid"],
+            user=users.User.from_row(sd),
             threadid=sd["threadid"],
             username=sd["username"],
             title=sd["title"],
diff --git a/src/littlesongplace/static/MatSaleh.otf b/src/littlesongplace/static/MatSaleh.otf
new file mode 100644 (file)
index 0000000..242494f
Binary files /dev/null and b/src/littlesongplace/static/MatSaleh.otf differ
diff --git a/src/littlesongplace/static/Unageo-ExtraBold-Italic.ttf b/src/littlesongplace/static/Unageo-ExtraBold-Italic.ttf
new file mode 100644 (file)
index 0000000..aca27f5
Binary files /dev/null and b/src/littlesongplace/static/Unageo-ExtraBold-Italic.ttf differ
diff --git a/src/littlesongplace/static/Unageo-ExtraBold.ttf b/src/littlesongplace/static/Unageo-ExtraBold.ttf
new file mode 100644 (file)
index 0000000..4a12295
Binary files /dev/null and b/src/littlesongplace/static/Unageo-ExtraBold.ttf differ
diff --git a/src/littlesongplace/static/Unageo-Medium-Italic.ttf b/src/littlesongplace/static/Unageo-Medium-Italic.ttf
new file mode 100644 (file)
index 0000000..6205886
Binary files /dev/null and b/src/littlesongplace/static/Unageo-Medium-Italic.ttf differ
diff --git a/src/littlesongplace/static/Unageo-Medium.ttf b/src/littlesongplace/static/Unageo-Medium.ttf
new file mode 100644 (file)
index 0000000..8d70fff
Binary files /dev/null and b/src/littlesongplace/static/Unageo-Medium.ttf differ
index cd695aadaca0a92cd22b4eeb9e884f789ea1c271..b369974306f8cd2c863c06c4b01c63a025756e90 100644 (file)
@@ -192,19 +192,19 @@ async function checkForNewActivity() {
 // Check for new activity every 10s
 setInterval(checkForNewActivity, 10000);
 
-function customImage(element) {
+function customImage(source, target) {
     // Customize an image by performing a palette swap on the .gif
     // file.  The source element must contain a data-img-b64 attribute
     // containing the base64 representation of a .gif file.  The byte
     // indexes match .gifs from Aseprite, and may not work for all
     // .gif files.
 
-    var style = window.getComputedStyle(document.body);
+    var style = window.getComputedStyle(target);
     var bgcolor = style.getPropertyValue("--yellow");
     var accolor = style.getPropertyValue("--purple");
 
     // Convert base64 string to Uint8Array so we can modify it
-    var data = atob(element.dataset.imgB64);
+    var data = atob(source.dataset.imgB64);
     var bytes = Uint8Array.from(data, c => c.charCodeAt(0));
 
     // Replace background color palette bytes in gif file
@@ -228,7 +228,7 @@ function updateImageColors() {
     // Perform a palette swap on all gifs based on current page colors
     document.querySelectorAll(".img-data").forEach(e => {
         document.querySelectorAll(`.${e.id}`).forEach(t => {
-            t.src = customImage(e);
+            t.src = customImage(e, t);
         });
     });
 }
index 174add73f81ee22bdde5ac2f3e3f25c58d71e068..e48fe811fce5acbf875ffafa899737ddaee6589f 100644 (file)
@@ -198,17 +198,17 @@ document.addEventListener("DOMContentLoaded", (event) => {
     var miniButton = document.getElementById("mini-play-pause-button");
     audio.addEventListener("play", (event) => {
         button.className = "lsp_btn_pause02";
-        button.src = customImage(document.getElementById("lsp_btn_pause02"));
+        button.src = customImage(document.getElementById("lsp_btn_pause02"), button);
         miniButton.className = "lsp_btn_pause02";
-        miniButton.src = customImage(document.getElementById("lsp_btn_pause02"));
+        miniButton.src = customImage(document.getElementById("lsp_btn_pause02"), button);
     })
 
     // Show play button when audio is paused
     audio.addEventListener("pause", (event) => {
         button.className = "lsp_btn_play02";
-        button.src = customImage(document.getElementById("lsp_btn_play02"));
+        button.src = customImage(document.getElementById("lsp_btn_play02"), button);
         miniButton.className = "lsp_btn_play02";
-        miniButton.src = customImage(document.getElementById("lsp_btn_play02"));
+        miniButton.src = customImage(document.getElementById("lsp_btn_play02"), button);
     })
 
     // Audio position scrubbing
index 8a143eaceb8ebb3db7a9ff2fdc392a50c48fa988..2133bd3ea1f7878b37e5d60dde657bcee53c01c4 100644 (file)
@@ -1,15 +1,46 @@
+/* Fonts */
+@font-face {
+    font-family: "Mat Saleh";
+    src: url("/static/MatSaleh.otf");
+}
+
+@font-face {
+    font-family: "Unageo";
+    src: url("/static/Unageo-Medium.ttf");
+}
+
+@font-face {
+    font-family: "Unageo";
+    src: url("/static/Unageo-Medium-Italic.ttf");
+    font-style: italic;
+}
+
+@font-face {
+    font-family: "Unageo";
+    src: url("/static/Unageo-ExtraBold.ttf");
+    font-weight: bold;
+}
+
+@font-face {
+    font-family: "Unageo";
+    src: url("/static/Unageo-ExtraBold-Italic.ttf");
+    font-weight: bold;
+    font-style: italic;
+}
+
 /* General */
 :root {
     --yellow: #e8e6b5;
-    --purple: #9373a9;
+    --purple: #b36fab;
     --blue: #44b7b7;
-    --black: #695c73;
+    --black: #514659;
+    --radius: 5px;
 }
 
 body {
     background: var(--yellow);
     color: var(--black);
-    font-family: sans-serif;
+    font-family: "Unageo", sans-serif;
     border-color: var(--purple);
     max-width: 700px;
     margin: auto;
@@ -21,22 +52,35 @@ a {
 
 h1, h2, h3, h4 {
     color: var(--purple);
+    font-family: "Mat Saleh", sans-serif;
+}
+
+h1 {
+    font-size: 40px;
+    text-align: center;
 }
 
 h2 {
-    font-size: 20px;
+    font-size: 26px;
+    /*border: 2px solid var(--purple);*/
+    box-shadow: 3px 3px 0px 0px var(--black);
+    background: var(--purple);
+    color: var(--yellow);
+    border-radius: var(--radius);
+    text-align: center;
+    padding: 5px;
 }
 
 h3 {
-    font-size: 16px;
+    font-size: 22px;
 }
 
 textarea {
-    font-family: sans-serif;
+    font-family: "Unageo", sans-serif;
     font-size: 16px;
     color: var(--black);
     border: 3px solid var(--purple);
-    border-radius: 10px;
+    border-radius: var(--radius);
     padding: 10px;
     background: var(--yellow);
     height: 200px;
@@ -49,11 +93,11 @@ textarea {
 input[type=text], input[type=password], input[type=url], input[type=datetime-local] {
     background: var(--yellow);
     margin: 10px;
-    font-family: sans-serif;
+    font-family: "Unageo", sans-serif;
     font-size: 16px;
     color: var(--black);
     border: 3px solid var(--purple);
-    border-radius: 10px;
+    border-radius: var(--radius);
     padding: 5px;
     width: 300px;
     max-width: calc(100% - 40px);
@@ -61,14 +105,14 @@ input[type=text], input[type=password], input[type=url], input[type=datetime-loc
 
 .button, input[type=submit] {
     cursor: pointer;
-    font-family: sans-serif;
+    font-family: "Unageo", sans-serif;
     font-size: 16px;
     font-weight: bold;
     text-decoration: none;
     color: var(--yellow);
     background: var(--purple);
     border: 0px;
-    border-radius: 5px;
+    border-radius: var(--radius);
     padding: 8px;
 }
 
@@ -76,7 +120,7 @@ select {
     border: none;
     background-color: var(--purple);
     color: var(--yellow);
-    border-radius: 5px;
+    border-radius: var(--radius);
     font-size: 16px;
     padding: 8px;
 }
@@ -88,14 +132,16 @@ div.main {
 }
 
 div.page-header {
-    box-shadow: 0px 0px 20px 0px;
-    border-radius: 10px;
+    box-shadow: 5px 5px 0px 0px var(--black);
+    border: 1px solid var(--black);
+    border-radius: var(--radius);
     margin: 10px;
+    padding: 5px;
 }
 
 .flashes {
     border: 3px solid var(--blue);
-    border-radius: 10px;
+    border-radius: var(--radius);
     margin: 20px;
 }
 
@@ -103,7 +149,7 @@ div.page-header {
     box-sizing: border-box;
     margin: 10px;
     border-width: 3px;
-    border-radius: 10px;
+    border-radius: var(--radius);
     border-style: solid;
     padding: 10px;
     background-color: var(--yellow);
@@ -125,18 +171,22 @@ div.page-header {
     display: flex;
     flex-wrap: wrap;
     gap: 10px;
+    justify-content: center;
 }
 
 .user-list-entry-container {
-    border-radius: 10px;
-    box-shadow: 0px 0px 5px 0px;
+    border-radius: var(--radius);
+    background: var(--black);
+    box-shadow: 2px 2px 0px 0px var(--black);
+    border: 1px solid var(--black);
+    overflow: hidden;
 }
 
 .user-list-entry {
     box-sizing: border-box;
     height: 100%;
     background: var(--yellow);
-    border-radius: 10px;
+    /*border-radius: var(--radius);*/
     padding: 5px;
 
     display: flex;
@@ -232,7 +282,7 @@ input[type=file] {
     max-width: 40%;
     background: var(--purple);
     padding: 5px;
-    border-radius: 10px;
+    border-radius: var(--radius);
 }
 
 .big-pfp {
@@ -241,13 +291,13 @@ input[type=file] {
     margin: 0px;
     padding: 0px;
     display: block;
-    border-radius: 5px;
+    border-radius: calc(var(--radius) / 2);
 }
 
 .small-pfp {
     max-width: 32px;
     max-height: 32px;
-    border-radius: 5px;
+    border-radius: calc(var(--radius) / 2);
     border: solid 2px var(--purple);
     background-color: var(--purple);
     vertical-align: middle;
@@ -270,8 +320,9 @@ input[type=file] {
 }
 
 .playlist-list-entry {
-    box-shadow: 0px 0px 5px 0px;
-    border-radius: 10px;
+    box-shadow: 3px 3px 0px 0px;
+    border-radius: var(--radius);
+    border: 1px solid var(--black);
     padding: 10px;
     margin: 10px 0px;
 }
@@ -286,7 +337,7 @@ input[type=file] {
 
 .draggable-song {
     box-shadow: 0px 0px 5px 0px;
-    border-radius: 10px;
+    border-radius: var(--radius);
     padding: 5px 10px;
     margin: 10px 0px;
     display: flex;
@@ -302,7 +353,7 @@ input[type=file] {
     height: 22px !important;
     left: 7px;
     right: auto;
-    border-radius: 5px;
+    border-radius: calc(var(--radius) / 2);
 }
 
 .clr-field input {
@@ -329,11 +380,15 @@ div.song-list-songs {
     display: flex;
     flex-direction: column;
     gap: 10px;
+    font-size: 14px;
 }
 
-.song-list-songs .song {
-    box-shadow: 0px 0px 5px 0px;
-    border-radius: 10px;
+div.song {
+    background: var(--yellow);
+    box-shadow: 2px 2px 0px 0px;
+    border-radius: var(--radius);
+    border: 1px solid var(--black);
+    overflow: hidden;
 }
 
 div.song-main {
@@ -347,6 +402,7 @@ div.song-main {
 }
 
 div.song-info {
+    font-family: "Unageo", sans-serif;
     display: flex;
     flex-wrap: wrap;
     flex-direction: row;
@@ -410,7 +466,7 @@ div.top-level-comment {
     margin-top: 10px;
     padding: 10px;
     box-shadow: 0px 0px 5px 0px;
-    border-radius: 10px;
+    border-radius: var(--radius);
 }
 
 div.reply-comment {
@@ -418,7 +474,7 @@ div.reply-comment {
     margin-bottom: 10px;
     padding: 10px;
     box-shadow: 0px 0px 5px 0px;
-    border-radius: 10px;
+    border-radius: var(--radius);
 }
 
 div.comment-button-container {
@@ -450,7 +506,7 @@ div.player {
     padding: 10px;
     padding-bottom: 0px;
     box-shadow: 0px 0px 20px 0px;
-    border-radius: 10px;
+    border-radius: var(--radius);
     background: var(--yellow);
 }
 
@@ -458,7 +514,7 @@ div.player {
     margin: 10px;
     padding-left: 10px;
     box-shadow: 0px 0px 20px 0px;
-    border-radius: 10px;
+    border-radius: var(--radius);
     background: var(--yellow);
 
     display: flex;
@@ -528,13 +584,13 @@ div.player-info {
 #position-slider::-webkit-slider-thumb {
     height: 20px;
     width: 20px;
-    border-radius: 10px;
+    border-radius: var(--radius);
 }
 
 #position-slider::-moz-range-thumb {
     height: 20px;
     width: 20px;
-    border-radius: 10px;
+    border-radius: var(--radius);
 }
 
 .player-button img {
@@ -558,7 +614,7 @@ div.comment-notification {
     margin: 10px;
     padding: 10px;
     box-shadow: 0px 0px 5px 0px;
-    border-radius: 10px;
+    border-radius: var(--radius);
 }
 
 /* Platform-specific global overrides */
@@ -567,3 +623,8 @@ div.comment-notification {
         display: none;
     }
 }
+
+/* Jam Events */
+.jam-event-list-title {
+    margin-left: 20px;
+}
index e453696fbebc1a78e189e44812b59679ddd6dfdd..939e9b5cd985fada9451637f4c352b3606088551 100644 (file)
@@ -4,39 +4,47 @@
 
 {% block body %}
 
-<h1>About littlesong.place</h1>
+<h1>about littlesong.place</h1>
 
 <p>
 Hello there, thanks for stopping by!
 </p>
 
+<h3>the little place</h3>
 <p>
 This site is meant to be a little place for your songs.  Of course, there are
 already lots of <em>big</em> places for songs out there.  But I wanted
 somewhere to share music that was free from algorithms, ads, rankings, and the
 general noise that comes with most of those big places.  A place that
 encourages and celebrates creativity, and a place for community with other
-humans.  If any of that resonates with you, then welcome!  I hope you enjoy
-your stay.
+humans.
+</p>
+<p>
+If any of that resonates with you, then welcome!  I hope you enjoy your stay.
 </p>
 
+<h3>the dream</h3>
 <p>
 I also love <a href="https://indreams.me">Dreams</a>, and the music community
 that formed there.  But now that live service support for Dreams has ended, and
 given the uncertain future of Media Molecule and the games industry more
 broadly, I worry that it's only a matter of time before the servers shut down
-for good.  Part of my goal with this site is to give others a place to archive
-their music from Dreams.  But beyond that, I hope it can also eventually become
-a similar platform for creativity and community of its own - albeit on a much
-smaller scale.
+for good.
+</p>
+<p>
+Part of my goal with this site is to give others a place to archive
+their music from Dreams.  But beyond that, my hope is that it can also
+eventually become a platform for creativity and community of its own - albeit
+on a much smaller scale.
 </p>
 
+<h3>the code</h3>
 <p>
 The site is open source!  You can
 <a href="https://github.com/cfulljames/littlesongplace">view it on GitHub</a>.
 </p>
 
-<h2>Contact Me!</h2>
+<h2>contact me!</h2>
 
 <p>
 I'm always looking for new ways to improve the site!  If you have ideas (or if
index d4ceb76cb7180403c73495c2fa545572ce3cd1b0..19f8f250f9591005a4f040d588489ff3a1688d09 100644 (file)
@@ -5,7 +5,7 @@
 {% block body %}
 
 {% if comments %}
-<h1>Activity</h1>
+<h1>activity</h1>
 
     {% for comment in comments %}
         <div class="comment-notification">
index a3075938fd8c9a905bdc76b60d3e0079699ddf2b..a81552a8b8802c61cb42ddff38305d5b8f6db6f8 100644 (file)
 
         <div class="page-header">
             <div style="text-align: center;">
-                <img class="title-image littlesongplace02">
+                <!--<img class="title-image littlesongplace02">-->
+                <h1>little song place</h1>
             </div>
             <!-- Navbar -->
             <div class="navbar">
                 <a href="/">Home</a>
+                <a href="/jams">Jams</a>
                 <a href="/about">About</a>
                 <a href="/site-news">News</a>
                 <a href="/songs">Random</a>
index 737904fc022900a8bd2c996dd41edaea441338ae..5843cf2216aad3078baf5eb8fe286b9c7d6efbe8 100644 (file)
@@ -4,7 +4,7 @@
 
 {% block body %}
 
-<h1>Write a Comment</h1>
+<h1>write a comment</h1>
 
 <p>
 {% if song -%}
index 4339084338369a8a6aa5c1e9201337fa64604108..d627aa818b4a0a53bb95004628c1c478d3af28b6 100644 (file)
@@ -4,24 +4,21 @@
 
 {% block body %}
 
-<h2>Hello!</h2>
-<p>
-🎶 Welcome to a little song place.  Make music, and share it with friends! ðŸŽµ
-</p>
+<h2>hello!</h2>
+<div style="display: flex; flex-direction: row; justify-content: center; gap: 10px; align-items: center;">
+<div>🎶</div>
+<div style="text-align: center;">Welcome to littlesong.place.<br/>Make music, and share it with friends!</div>
+<div>🎵</div>
+</div>
 
 {% if ongoing_events or upcoming_events %}
-<h2>Jams</h2>
+<h2>happenings</h2>
 {% from "jam-event-list.html" import jam_event_list %}
-{{ jam_event_list("Ongoing Events", ongoing_events, "Ends", "end") }}
-{{ jam_event_list("Upcoming Events", upcoming_events, "Starts", "start") }}
+{{ jam_event_list("ongoing events", ongoing_events, "ends", "end") }}
+{{ jam_event_list("upcoming events", upcoming_events, "starts", "start") }}
 {% endif %}
 
-<h2>Humans</h2>
-<p>
-Check out the music and profiles of the fine folks below!
-{% if not session["userid"] %}If you create an account, you'll show up here too.{% endif %}
-</p>
-
+<h2>humans</h2>
 <div class="user-list">
     {% for user in users %}
     <div class="user-list-entry-container">
@@ -35,8 +32,7 @@ Check out the music and profiles of the fine folks below!
     {% endfor %}
 </div>
 
-<h2>Hot New Tunes</h2>
-<p>Listen to the 50 latest tracks!</p>
+<h2>hot new tunes</h2>
 {% include "song-list.html" %}
 
 {% endblock %}
index cf7716fa4881f73fcf11140bd53cf965aa76b73d..d70bdb610d85c42f07c5ea1e81f834bdf632b09d 100644 (file)
@@ -1,6 +1,6 @@
 {% macro jam_event_list(list_title, events, date_label, which_date) %}
 {% if events %}
-<h3>{{ list_title }}</h3>
+<h3 class="jam-event-list-title">{{ list_title }}</h3>
 <ul class="jam-event-list">
     {% for event in events %}
     <li class="jam-event-list-entry">
@@ -9,12 +9,12 @@
             <a href="/jams/{{ event.jamid }}/events/{{ event.eventid }}">[Upcoming Event]</a>
         </span>
         {%- else -%}
-        <span class="jam-event-list-title">
+        <span>
             <a href="/jams/{{ event.jamid }}/events/{{ event.eventid }}">{{ event.title }}</a>
         </span>
         {%- endif %}
         <strong>&nbsp;|&nbsp;</strong>
-        <span class="jam-event-list-jam-title">
+        <span>
             <a href="/jams/{{ event.jamid }}">{{ event.jam_title }}</a>
         </span>
         <strong>&nbsp;|&nbsp;</strong>
index b9988f90a15ce6900486f6f37b72912e35ab9771..0d3cad93df1ac2a39252963eeb5a5d62eaef55fa 100644 (file)
@@ -4,20 +4,23 @@
 
 {% block body %}
 
-<h1>{% if event.hidden -%}[Upcoming Event]{%- else -%}{{ event.title }}{%- endif %} - {{ jam.title }}</h1>
+<h1>{% if event.hidden -%}[Upcoming Event]{%- else -%}{{ event.title }}{%- endif %}</h1>
 
 <div id="jam-event-view">
     <div class="info">
-        <strong>Host:</strong>
+        <strong>jam:</strong>
+            <a href="/jams/{{ jam.jamid }}">{{ jam.title }}</a>
+            <br/>
+        <strong>host:</strong>
             <a href="/users/{{ jam.ownername }}" class="profile-link">{{ jam.ownername }}</a>
             <br/>
         {% if event.startdate %}
-        <strong>Start Date:</strong>
+        <strong>start date:</strong>
             <span class="date" data-date="{{ event.startdate.isoformat() }}"><!-- Populated by nav.js --></span>
             <br/>
         {% endif %}
         {% if event.enddate %}
-        <strong>End Date:</strong>
+        <strong>end date:</strong>
             <span class="date" data-date="{{ event.enddate.isoformat() }}"><!-- Populated by nav.js --></span>
         {% endif %}
     </div>
     </div>
 
     <h2>About the Jam</h2>
-    <div>
-        <strong><a href="/jams/{{ jam.jamid }}">{{ jam.title }}</a></strong>
-    </div>
-    <br/>
     <div>
     {{ (jam.description.replace("\n", "<br>"))|safe }}
     </div>
index 1eca7094b096da7e8eff2d4153b3902d75e53e01..bf595aa323e1d7fd4f2687d49a799485813f6525 100644 (file)
@@ -8,7 +8,7 @@
 
 <div id="jam-view">
     <div>
-        <strong>Host:</strong>
+        <strong>host:</strong>
         <a href="/users/{{ jam.ownername }}" class="profile-link">{{ jam.ownername }}</a>
     </div>
     <br/>
     </div>
     {%- endif %}
 
-    <h2>Description</h2>
+    <h2>description</h2>
     <div>
     {{ (jam.description.replace("\n", "<br>"))|safe }}
     </div>
 
-    <h2>Events</h2>
+    <h2>events</h2>
     {%- if jam.ownerid == session["userid"] -%}
     <a class="song-list-button" title="Create Event" href="/jams/{{ jam.jamid }}/events/create"><img class="lsp_btn_add02" /></a>
     {%- endif -%}
 
     {% from "jam-event-list.html" import jam_event_list %}
-    {{ jam_event_list("Ongoing Events", ongoing, "Ends", "end") }}
-    {{ jam_event_list("Upcoming Events", upcoming, "Starts", "start") }}
-    {{ jam_event_list("Past Events", past, "Ended", "end") }}
+    {{ jam_event_list("ongoing events", ongoing, "ends", "end") }}
+    {{ jam_event_list("upcoming events", upcoming, "starts", "start") }}
+    {{ jam_event_list("past events", past, "ended", "end") }}
 </div> <!-- jam-view -->
 
 {% if session["userid"] == jam.ownerid -%}
index 435c6bd5d851211fcd9cda1b19397d6788c9bb0a..ccec74608935b4f727561ad09a556067e9645171 100644 (file)
@@ -4,15 +4,15 @@
 
 {% block body %}
 
-<h1>Jams</h1>
+<h1>jams</h1>
 
-<h2>Events</h2>
+<h2>events</h2>
 {% from "jam-event-list.html" import jam_event_list %}
-{{ jam_event_list("Ongoing Events", ongoing, "Ends", "end") }}
-{{ jam_event_list("Upcoming Events", upcoming, "Starts", "start") }}
-{{ jam_event_list("Recent Events", past, "Ended", "end") }}
+{{ jam_event_list("ongoing events", ongoing, "ends", "end") }}
+{{ jam_event_list("upcoming events", upcoming, "starts", "start") }}
+{{ jam_event_list("recent events", past, "ended", "end") }}
 
-<h2>All Jams</h2>
+<h2>all jams</h2>
 <ul class="jam-list">
     {% for jam in jams -%}
     <li><a href="/jams/{{ jam.jamid }}">{{ jam.title }}</a></li>
index 9c17e3950f054ca4615d11c318aba66bbcb1f738..13ae56484c740f8c1770ae4e63d2159c23a6496b 100644 (file)
@@ -4,7 +4,7 @@
 
 {% block body %}
 
-<h1>Sign In</h1>
+<h1>sign in</h1>
 
 {% if note %}
 <div class="note">{{ note }}</div>
index 8a2904bbe589a2f40e1c243eece26daa6b022f5d..619f2bd532e1e0bc04e759ad8472c3d036f80120 100644 (file)
@@ -4,12 +4,12 @@
 
 {% block body %}
 
-<h1>Site News</h1>
+<h1>site news</h1>
 
-<h2>2025-04-20 - little song jam</h2>
+<h2>2025-04-26 - little song jam</h2>
 <p>
-Get ready!  The first little song jam starts next week!  I've been hard at work
-building the new jam system for the site, and it's finally done.
+Get ready!  The first little song jam is here!  I've been hard at work building
+the new jam system for the site, and it's finally done.
 </p>
 <p>
 The current plan is to host a week-long jam once a month.  The theme will be
@@ -20,6 +20,8 @@ and upload it on the jam event page, and then I'll host a listening party on
 
 <ul>
     <li>New <a href="/jams/1">jam page</a>!</li>
+    <li>New fonts</li>
+    <li>Lots of visual tweaks</li>
 </ul>
 
 <h2>2025-04-06 - Open Source</h2>
index 5240e8949d17c062e407a23a3de7f16cade9f8c2..21dc231421df2c5468f5cf5176d093810df8d206 100644 (file)
 
 {% if session["userid"] == userid or playlists -%}
 <div id="profile-playlists">
-    <h2>Playlists</h2>
+    <h2>playlists</h2>
 
     <!-- Add Playlist button/form -->
     {% if session["userid"] == userid -%}
 
 {% if session["userid"] == userid or songs %}
 <div id="profile-songs">
-    <h2>Songs</h2>
+    <h2>songs</h2>
 
     <!-- Add Song button -->
     {% if session["userid"] == userid %}
 
 {% endif %}
 
-<h2>Comments</h2>
+<h2>comments</h2>
 {{ comment_thread(threadid, session['userid'], userid, comments) }}
 
 {% endblock %}
index 09bd89369083c3025ac53108b528606da192300f..9757eae85b9a4252d79b3902552106f627889600 100644 (file)
@@ -3,7 +3,7 @@
 {% block title %}Create Account{% endblock %}
 
 {% block body %}
-<h1>Create a new account</h1>
+<h1>create a new account</h1>
 <p>Welcome to the site!</p>
 <form method="post">
     <div class="signup-form">
index a733accd467c3935b042ad1f203f9e4062908a3a..b333980881e8982fb212028388d037c9c432ee12 100644 (file)
@@ -50,14 +50,14 @@ function showDetails(event) {
         songDetails.hidden = false;
         detailsToggle.alt = "Hide Details";
         detailsToggle.className = "lsp_btn_hide02";
-        detailsToggle.src = customImage(document.getElementById("lsp_btn_hide02"));
+        detailsToggle.src = customImage(document.getElementById("lsp_btn_hide02"), detailsToggle);
     }
     else {
         // Hide details
         songDetails.hidden = true;
         detailsToggle.alt = "Show Details";
         detailsToggle.className = "lsp_btn_show02";
-        detailsToggle.src = customImage(document.getElementById("lsp_btn_show02"));
+        detailsToggle.src = customImage(document.getElementById("lsp_btn_show02"), detailsToggle);
     }
     return false;
 }
index 55cb11c9994dda066abacddc3c6a2c87c4d1a19e..7a3e1c518a606b601efb30a87df9fc7b65e238fd 100644 (file)
@@ -4,7 +4,7 @@
 
 {% block body %}
 
-<h1>Songs</h1>
+<h1>songs</h1>
 
 {% if user %}
     <div class="filter">
index 73cc3fdd9e9fb08dbd9f81d1c4ee4d3974a1c4ae..857196d48e29af698aae92b814a5007492d0b57b 100644 (file)
@@ -1,5 +1,35 @@
+from dataclasses import dataclass
+
 from . import colors, datadir, db
 
+@dataclass
+class User:
+    userid: int
+    username: str
+    fgcolor: str
+    bgcolor: str
+    accolor: str
+
+    @property
+    def colors(self):
+        return {
+            "fgcolor": self.fgcolor,
+            "bgcolor": self.bgcolor,
+            "accolor": self.accolor,
+        }
+
+    @classmethod
+    def from_row(cls, row):
+        user_colors = get_user_colors(row)
+        return User(
+                userid=row["userid"],
+                username=row["username"],
+                **user_colors)
+
+def by_id(userid):
+    user_data = db.query("select * from users where userid = ?", [userid], one=True)
+    return User.from_row(user_data)
+
 def user_has_pfp(userid):
     return (datadir.get_user_images_path(userid)/"pfp.jpg").exists()
 
index 9a78051c9a396457d01f62382b45d6a818cda5c1..17afbac140d3bf044484609fac37dd4827b8e69d 100644 (file)
@@ -5,7 +5,7 @@ from .utils import create_user, post_signup_form
 
 def test_signup_get(client):
     response = client.get("/signup")
-    assert b"Create a new account" in response.data
+    assert b"create a new account" in response.data
 
 def test_signup_success(client):
     response = post_signup_form(client, "user", "password")
index c1ea34a53c0a1aa0047c5e51c926d9bd0b678cf4..edf1b2ba99b7d3067227448c6aa1c1742d633a90 100644 (file)
@@ -223,17 +223,17 @@ def test_jam_events_sorted_on_jams_page(client, user, jam):
     _assert_appear_in_order(
             response.data,
             [
-                b"Ongoing Events",
+                b"ongoing events",
                 b"OngoingJam",
 
-                b"Upcoming Events",
+                b"upcoming events",
                 b"[Upcoming Event]", # Upcoming jam name hidden
                 b"[Upcoming Event]", # Upcoming jam name hidden
 
-                b"Recent Events",
+                b"recent events",
                 b"PastJam",
 
-                b"All Jams",
+                b"all jams",
                 b"New Jam",
                 b"New Jam",
             ])
@@ -247,13 +247,13 @@ def test_jam_events_sorted_on_jam_info_page(client, user, jam):
     _assert_appear_in_order(
             response.data,
             [
-                b"Ongoing Events",
+                b"ongoing events",
                 b"OngoingJam",
 
-                b"Upcoming Events",
+                b"upcoming events",
                 b"[Upcoming Event]", # Upcoming jam name hidden
 
-                b"Past Events",
+                b"past events",
                 b"PastJam",
             ])