DATA_DIR = Path(os.environ["DATA_DIR"]) if "DATA_DIR" in os.environ else Path(".")
SCRIPT_DIR = Path(__file__).parent
+BGCOLOR = "#e8e6b5"
+FGCOLOR = "#695c73"
+ACCOLOR = "#9373a9"
+
################################################################################
# Logging
################################################################################
name=profile_username,
userid=profile_userid,
bio=profile_bio,
- fgcolor=profile_data["fgcolor"],
- bgcolor=profile_data["bgcolor"],
- accolor=profile_data["accolor"],
+ bgcolor=profile_data["bgcolor"] or BGCOLOR,
+ fgcolor=profile_data["fgcolor"] or FGCOLOR,
+ accolor=profile_data["accolor"] or ACCOLOR,
playlists=plist_data,
songs=songs,
user_has_pfp=(get_user_images_path(profile_userid)/"pfp.jpg").exists(),
"song.html",
songs=[song],
song=song,
- bgcolor=user_data["bgcolor"],
- fgcolor=user_data["fgcolor"],
- accolor=user_data["accolor"])
+ bgcolor=user_data["bgcolor"] or BGCOLOR,
+ fgcolor=user_data["fgcolor"] or FGCOLOR,
+ accolor=user_data["accolor"] or ACCOLOR)
except ValueError:
abort(404)
else:
private=plist_data["private"],
userid=plist_data["userid"],
username=plist_data["username"],
- bgcolor=plist_data["bgcolor"],
- fgcolor=plist_data["fgcolor"],
- accolor=plist_data["accolor"],
+ bgcolor=plist_data["bgcolor"] or BGCOLOR,
+ fgcolor=plist_data["fgcolor"] or FGCOLOR,
+ accolor=plist_data["accolor"] or ACCOLOR,
songs=songs)
def flash_and_log(msg, category=None):
document.querySelectorAll(".nav-logged-out").forEach((e) => {e.hidden = loggedIn;});
if (loggedIn) {
document.getElementById("logged-in-status").innerText = `Signed in as ${username}`;
+ document.getElementById("my-profile").href = `/users/${username}`;
}
// Update activity indicator status
if (urlIsOnSameSite(targetUrl)) {
event.preventDefault();
event.stopPropagation();
- fetch(targetUrl, {redirect: "follow"}).then(handleAjaxResponse);
+ fetch(targetUrl, {redirect: "follow"}).then(handleAjaxResponse).catch((err) => console.log(err));
}
}
event.stopPropagation();
var formData = new FormData(event.target);
fetch(targetUrl, {redirect: "follow", body: formData, method: event.target.method})
- .then(handleAjaxResponse);
+ .then(handleAjaxResponse)
+ .catch((err) => window.location.reload()); // Failed to submit form; just reload page (should never happen)
}
}
}
async function handleAjaxResponse(response) {
+ if (response.status != 200) {
+ window.location.href = response.url;
+ }
// Update URL in browser window, minus request-type field
var url = new URL(response.url);
url.searchParams.delete("request-type");
// Replace the contents of the current page with those from data
if (!data) {
- fetch(window.location.href, {redirect: "follow"}).then(handleAjaxResponse);
+ fetch(window.location.href, {redirect: "follow"}).then(handleAjaxResponse).catch((err) => window.location.reload());
return;
}
var parser = new DOMParser();
<a href="/">Home</a>
<a href="/site-news">News</a>
- <a href="/users/{{ session["username"] }}" class="nav-logged-in" hidden>My Profile</a>
+ <a href="/users/{{ session["username"] }}" class="nav-logged-in" id="my-profile" hidden>My Profile</a>
<a href="/activity"><span id="activity-indicator" hidden></span>Activity</a>
<a href="/logout" class="nav-logged-in" hidden>Sign Out</a>
NOW
-- AJAX pages so songs can play during navigation
- - Use correct content type header for response
- - HTTP Error handling
-- Break up main.py, test_offline.py
-- Pinned profile playlists
SOON
+- Break up main.py, test_offline.py
+- Pinned profile playlists
- Image support in comments, descriptions, bios, etc.
- Player minimize button
- Shuffle all page