class Song:
songid: int
userid: int
+ username: str
title: str
description: str
tags: list[str]
@classmethod
def by_id(cls, songid):
- songs = cls._from_db("select * from songs where songid = ?", [songid])
+ songs = cls._from_db("select * from songs inner join users on songs.userid = users.userid where songid = ?", [songid])
if not songs:
raise ValueError(f"No song for ID {songid:d}")
@classmethod
def get_all_for_user(cls, userid):
- return cls._from_db("select * from songs where userid = ? order by created desc", [userid])
+ return cls._from_db("select * from songs inner join users on songs.userid = users.userid where songs.userid = ? order by songs.created desc", [userid])
@classmethod
def get_all_for_tag(cls, tag):
- return cls._from_db("select * from song_tags inner join songs on song_tags.songid = songs.songid where tag = ?", [tag])
+ return cls._from_db("select * from song_tags inner join songs on song_tags.songid = songs.songid inner join users on songs.userid = users.userid where tag = ?", [tag])
@classmethod
def _from_db(cls, query, args=()):
for sd in songs_data:
song_tags = [t["tag"] for t in tags[sd["songid"]]]
song_collabs = [c["name"] for c in collabs[sd["songid"]]]
- songs.append(cls(sd["songid"], sd["userid"], sd["title"], sd["description"], song_tags, song_collabs))
+ songs.append(cls(sd["songid"], sd["userid"], sd["username"], sd["title"], sd["description"], song_tags, song_collabs))
return songs
audio.src = `/song/${songData.userid}/${songData.songid}`;
audio.currentTime = 0;
audio.play();
+
+ var title = document.getElementById("player-title");
+ title.textContent = songData.title;
+
+ var separator = document.getElementById("player-info-sep");
+ separator.hidden = false;
+
+ var artist = document.getElementById("player-artist");
+ artist.textContent = songData.username;
+ artist.href = `/users/${songData.username}`;
+ artist.hidden = false;
}
// Play or pause the current song in the player
/* Song Player */
div.player {
position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 100px;
+ border: 3px solid #000;
+ background: #fff;
+}
+
+div.player-info {
+ height: 50%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
gap: 10px;
- bottom: 0;
- left: 0;
- right: 0;
- height: 50px;
- border: 3px solid #000;
- background: #fff;
+}
+
+div.player-controls {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ height: 50%;
}
a.player-button {
<title>{% block title %} Base {% endblock %}</title>
<link rel="stylesheet" href="/static/styles.css">
<script src="/static/player.js"></script>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<!-- Navbar -->
<!-- Song Player -->
<div class="player">
- <a href="javascript:songPrevious()" class="player-button"><<</a>
- <a href="javascript:songPlayPause()" class="player-button">></a>
- <a href="javascript:songNext()" class="player-button">>></a>
- <div id="player-position">
- <span id="player-position-bar"></span>
- <span id="player-position-dot"></span>
+ <div class="player-info">
+ <!-- TODO: Show song title, artist -->
+ <span id="player-title">Not Playing</span>
+ <span id="player-info-sep" hidden>-</span>
+ <a id="player-artist" hidden></span>
+ </div>
+ <div class="player-controls">
+ <a href="javascript:songPrevious()" class="player-button"><<</a>
+ <a href="javascript:songPlayPause()" class="player-button">></a>
+ <a href="javascript:songNext()" class="player-button">>></a>
+ <div id="player-position">
+ <span id="player-position-bar"></span>
+ <span id="player-position-dot"></span>
+ </div>
+ <span class="player-time" id="player-current-time">0:00</span>
+ <span class="player-time-sep">/</span>
+ <span class="player-time" id="player-total-time">0:00</span>
+ <audio id="player-audio"></audio>
+ <!-- TODO: Volume control -->
</div>
- <span class="player-time" id="player-current-time">0:00</span>
- <span class="player-time-sep">/</span>
- <span class="player-time" id="player-total-time">0:00</span>
- <audio id="player-audio"></audio>
- <!-- TODO: Show song title, artist -->
- <!-- TODO: Volume control -->
</div>
</body>
</html>
<!-- Song Title -->
<div class="song-title">{{ song.title }}</div>
+ <!-- Song Artist -->
+ <a href="/users/{{ song.username }}" class="song-username">{{ song.username }}</a>
+
<!-- Owner-Specific Buttons (Edit/Delete) -->
{% if session["userid"] == song.userid %}
<div class="song-edit-button">
-- automated tests
+PRIORITIES??
+- Player: Show song/artist
+- Player: Use session storage to continue song after load
+- Song List: Show/Hide Details
+- Song List: Show details when song plays, hide after
+- Mobile browser support
+- CSS/Design
+- AJAX pages so songs can play without glitching during navigation
+- Automated Tests
+- RELEASE IT
+- Play Queue:
+ - Add songs
+ - View songs in queue
+ - Remove songs
+ - Reorder songs
+ - Automatically use songs on page when queue ends
+- Playlists:
+ - Create
+ - Play
+ - Remove song
+ - Reorder songs
+ - Delete
+ - Pin to profile
+ - Albums?
+- Comments:
+ - Leave comment
+ - Delete comment
+ - Notifications
+- Song Search
+
-- javascript song player:
- - song queue
- limit input length for form fields (back and front end)
- admin account(s)
- logging
-- css/design
- playlists
- homepage activity log