pride flags
78
_server.py
|
@ -1,3 +1,6 @@
|
||||||
|
# MAKE SURE YOU INSTALL ALL NEEDED LIBRARIES!
|
||||||
|
# pip install flask dotindex ensure-file
|
||||||
|
|
||||||
CONTENT_DIRECTORY = "./public/"
|
CONTENT_DIRECTORY = "./public/"
|
||||||
SAVING_DIRECTORY = "./save/"
|
SAVING_DIRECTORY = "./save/"
|
||||||
|
|
||||||
|
@ -12,6 +15,7 @@ import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from DotIndex import DotIndex
|
from DotIndex import DotIndex
|
||||||
|
from ensure_file import ensure_file
|
||||||
from typing import Union, Callable
|
from typing import Union, Callable
|
||||||
from flask import request, redirect
|
from flask import request, redirect
|
||||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
@ -19,6 +23,36 @@ from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
app.url_map.strict_slashes = False
|
app.url_map.strict_slashes = False
|
||||||
|
|
||||||
|
FLAGS = {
|
||||||
|
"agender": "Agender",
|
||||||
|
"ally": "Ally",
|
||||||
|
"aroace": "Aroace",
|
||||||
|
"aro": "Aromantic",
|
||||||
|
"ace": "Asexual",
|
||||||
|
"bicurious": "Bicurious",
|
||||||
|
"bigender": "Bigender",
|
||||||
|
"bi": "Bisexual",
|
||||||
|
"cisgender": "Cisgender",
|
||||||
|
"demiboy": "Demiboy",
|
||||||
|
"demigirl": "Demigirl",
|
||||||
|
"demiromantic": "Demiromantic",
|
||||||
|
"demisexual": "Demisexual",
|
||||||
|
"gay": "Gay (Rainbow)",
|
||||||
|
"gayman": "Gay Man",
|
||||||
|
"genderfluid": "Genderfluid",
|
||||||
|
"intersex": "Intersex",
|
||||||
|
"lesbian": "Lesbian",
|
||||||
|
"nonbinary": "Nonbinary",
|
||||||
|
"omnigender": "Omnigender",
|
||||||
|
"pan": "Pansexual",
|
||||||
|
"polyamory": "Polyamorous",
|
||||||
|
"straight": "Straight",
|
||||||
|
"transfem": "Transfeminine",
|
||||||
|
"trans": "Transgender",
|
||||||
|
"transmasc": "Transmasculine"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SOCIALS_REGEX = {
|
SOCIALS_REGEX = {
|
||||||
"discord" : re.compile(r"^(?!.*\.\.)(?=.{2,32}$)[a-z0-9_.]+$"),
|
"discord" : re.compile(r"^(?!.*\.\.)(?=.{2,32}$)[a-z0-9_.]+$"),
|
||||||
"twitter" : re.compile(r"^(?!.*twitter)(?!.*admin)[a-z0-9_]{1,15}$", re.IGNORECASE),
|
"twitter" : re.compile(r"^(?!.*twitter)(?!.*admin)[a-z0-9_]{1,15}$", re.IGNORECASE),
|
||||||
|
@ -126,24 +160,6 @@ def sha(string: Union[str, bytes]) -> str:
|
||||||
return hashlib.sha256(string).hexdigest()
|
return hashlib.sha256(string).hexdigest()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def ensure_file(path: str, *, default_value: str="", folder: bool=False) -> None:
|
|
||||||
if os.path.exists(path):
|
|
||||||
if folder and not os.path.isdir(path):
|
|
||||||
os.remove(path)
|
|
||||||
os.makedirs(path)
|
|
||||||
elif not folder and os.path.isdir(path):
|
|
||||||
shutil.rmtree(path, ignore_errors=True)
|
|
||||||
f = open(path, "w")
|
|
||||||
f.write(default_value)
|
|
||||||
f.close()
|
|
||||||
else:
|
|
||||||
if folder:
|
|
||||||
os.makedirs(path)
|
|
||||||
else:
|
|
||||||
f = open(path, "w")
|
|
||||||
f.write(default_value)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def escape_html(string: str) -> str:
|
def escape_html(string: str) -> str:
|
||||||
return string.replace("&", "&").replace("<", "<").replace("\"", """)
|
return string.replace("&", "&").replace("<", "<").replace("\"", """)
|
||||||
|
|
||||||
|
@ -226,11 +242,10 @@ def get_template(json, username):
|
||||||
inner = add_to_output(inner, json, "compliments", "Compliments");
|
inner = add_to_output(inner, json, "compliments", "Compliments");
|
||||||
inner = add_to_output(inner, json, "relationship", "Relationship<br>Descriptions");
|
inner = add_to_output(inner, json, "relationship", "Relationship<br>Descriptions");
|
||||||
|
|
||||||
try:
|
if "social" in json and len(json.social):
|
||||||
social = json.social # type: ignore
|
|
||||||
inner += '<div class="added" id="social"><h2>Social Links</h2>'
|
inner += '<div class="added" id="social"><h2>Social Links</h2>'
|
||||||
|
|
||||||
for i in social:
|
for i in json.social:
|
||||||
if SOCIAL_INFO[i[1]]["link"]:
|
if SOCIAL_INFO[i[1]]["link"]:
|
||||||
inner += f"<div>{SOCIAL_ICONS[i[1]]} <a href='{SOCIAL_INFO[i[1]]['link'].replace('%q', i[0])}' target='_blank'>{SOCIAL_INFO[i[1]]['prefix']}{escape_html(i[0])}</a></div>"
|
inner += f"<div>{SOCIAL_ICONS[i[1]]} <a href='{SOCIAL_INFO[i[1]]['link'].replace('%q', i[0])}' target='_blank'>{SOCIAL_INFO[i[1]]['prefix']}{escape_html(i[0])}</a></div>"
|
||||||
else:
|
else:
|
||||||
|
@ -238,10 +253,15 @@ def get_template(json, username):
|
||||||
|
|
||||||
inner += "</div>"
|
inner += "</div>"
|
||||||
|
|
||||||
except AttributeError as e:
|
if "flags" in json and len(json.flags):
|
||||||
print(e)
|
inner += '<div class="added" id="flags"><h2>Pride Flags</h2><div class="img-list">'
|
||||||
|
|
||||||
inner += "</div>"
|
for i in json.flags:
|
||||||
|
inner += f'<img src="/img/flags/{i}.png" title="{FLAGS[i]}">'
|
||||||
|
|
||||||
|
inner += "</div></div>"
|
||||||
|
|
||||||
|
inner += f'</div><div id="key">Key:<br>{icons["4"]} - Great<br>{icons["3"]} - Good<br>{icons["2"]} - Okay<br>{icons["1"]} - Bad</div><footer>Icons from <a href="https://fontawesome.com" target="_blank">Font Awesome</a></footer>'
|
||||||
|
|
||||||
return title, inner, styles, embed
|
return title, inner, styles, embed
|
||||||
|
|
||||||
|
@ -535,6 +555,13 @@ def api_save():
|
||||||
social.append(i)
|
social.append(i)
|
||||||
user_data["social"] = sort_list(social, True)
|
user_data["social"] = sort_list(social, True)
|
||||||
|
|
||||||
|
if "flags" in x:
|
||||||
|
flags = {}
|
||||||
|
for i in x["flags"]:
|
||||||
|
if i in FLAGS:
|
||||||
|
flags[i] = None
|
||||||
|
user_data["flags"] = sorted([i for i in flags])
|
||||||
|
|
||||||
f = open(f"{SAVING_DIRECTORY}{username}.json", "w")
|
f = open(f"{SAVING_DIRECTORY}{username}.json", "w")
|
||||||
f.write(json.dumps(user_data))
|
f.write(json.dumps(user_data))
|
||||||
f.close()
|
f.close()
|
||||||
|
@ -590,8 +617,9 @@ app.route("/editor")(create_file_serve("editor.html"))
|
||||||
app.route("/u/<path:user>")(get_user_page)
|
app.route("/u/<path:user>")(get_user_page)
|
||||||
app.route("/home")(home)
|
app.route("/home")(home)
|
||||||
|
|
||||||
app.route("/js/<path:file>")(create_folder_serve("js"))
|
|
||||||
app.route("/css/<path:file>")(create_folder_serve("css"))
|
app.route("/css/<path:file>")(create_folder_serve("css"))
|
||||||
|
app.route("/img/flags/<path:file>")(create_folder_serve("img/flags"))
|
||||||
|
app.route("/js/<path:file>")(create_folder_serve("js"))
|
||||||
|
|
||||||
app.route("/api/account/login", methods=["POST"])(api_account_login)
|
app.route("/api/account/login", methods=["POST"])(api_account_login)
|
||||||
app.route("/api/account/signup", methods=["POST"])(api_account_signup)
|
app.route("/api/account/signup", methods=["POST"])(api_account_signup)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
function load(fromStart) {
|
function load(fromStart) {
|
||||||
if (fromStart) { next = 0; }
|
if (fromStart) { next = 0; }
|
||||||
fetch(`/api/browse?sort=alphabetical&page=${next}`, {
|
fetch(`/api/browse?sort=random&page=${next}`, {
|
||||||
"method": "GET"
|
"method": "GET"
|
||||||
}).then((request) => (request.json()))
|
}).then((request) => (request.json()))
|
||||||
.then((json) => {
|
.then((json) => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
body {
|
body {
|
||||||
padding-bottom: calc(20px + 8em);
|
padding-bottom: calc(30px + 8em);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
|
@ -26,6 +26,19 @@ footer a, footer a:visited, footer a:link {
|
||||||
white-space: break-word;
|
white-space: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.added .img-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
column-gap: 0.5em;
|
||||||
|
max-width: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.added img {
|
||||||
|
max-width: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
.added h2 {
|
.added h2 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
BIN
public/img/flags/ace.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
public/img/flags/agender.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
public/img/flags/ally.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
public/img/flags/aro.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
public/img/flags/aroace.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
public/img/flags/bi.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
public/img/flags/bicurious.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
public/img/flags/bigender.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
public/img/flags/cisgender.png
Normal file
After Width: | Height: | Size: 8 KiB |
BIN
public/img/flags/demiboy.png
Normal file
After Width: | Height: | Size: 9 KiB |
BIN
public/img/flags/demigirl.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
public/img/flags/demiromantic.png
Normal file
After Width: | Height: | Size: 230 KiB |
BIN
public/img/flags/demisexual.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
public/img/flags/gay.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
public/img/flags/gayman.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
public/img/flags/genderfluid.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
public/img/flags/intersex.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
public/img/flags/lesbian.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
public/img/flags/nonbinary.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
public/img/flags/omnigender.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
public/img/flags/pan.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
public/img/flags/polyamory.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
public/img/flags/straight.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
public/img/flags/trans.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
public/img/flags/transfem.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
public/img/flags/transmasc.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
|
@ -158,6 +158,35 @@ const socialRegex = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const flags = {
|
||||||
|
agender: "Agender",
|
||||||
|
ally: "Ally",
|
||||||
|
aroace: "Aroace",
|
||||||
|
aro: "Aromantic",
|
||||||
|
ace: "Asexual",
|
||||||
|
bicurious: "Bicurious",
|
||||||
|
bigender: "Bigender",
|
||||||
|
bi: "Bisexual",
|
||||||
|
cisgender: "Cisgender",
|
||||||
|
demiboy: "Demiboy",
|
||||||
|
demigirl: "Demigirl",
|
||||||
|
demiromantic: "Demiromantic",
|
||||||
|
demisexual: "Demisexual",
|
||||||
|
gay: "Gay (Rainbow)",
|
||||||
|
gayman: "Gay Man",
|
||||||
|
genderfluid: "Genderfluid",
|
||||||
|
intersex: "Intersex",
|
||||||
|
lesbian: "Lesbian",
|
||||||
|
nonbinary: "Nonbinary",
|
||||||
|
omnigender: "Omnigender",
|
||||||
|
pan: "Pansexual",
|
||||||
|
polyamory: "Polyamorous",
|
||||||
|
straight: "Straight",
|
||||||
|
transfem: "Transfeminine",
|
||||||
|
trans: "Transgender",
|
||||||
|
transmasc: "Transmasculine"
|
||||||
|
}
|
||||||
|
|
||||||
const icons = {
|
const icons = {
|
||||||
1: '<svg style="fill: var(--text-low-opacity);" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M323.8 477.2c-38.2 10.9-78.1-11.2-89-49.4l-5.7-20c-3.7-13-10.4-25-19.5-35l-51.3-56.4c-8.9-9.8-8.2-25 1.6-33.9s25-8.2 33.9 1.6l51.3 56.4c14.1 15.5 24.4 34 30.1 54.1l5.7 20c3.6 12.7 16.9 20.1 29.7 16.5s20.1-16.9 16.5-29.7l-5.7-20c-5.7-19.9-14.7-38.7-26.6-55.5-5.2-7.3-5.8-16.9-1.7-24.9s12.3-13 21.3-13H448c8.8 0 16-7.2 16-16 0-6.8-4.3-12.7-10.4-15-7.4-2.8-13-9-14.9-16.7s.1-15.8 5.3-21.7c2.5-2.8 4-6.5 4-10.6 0-7.8-5.6-14.3-13-15.7-8.2-1.6-15.1-7.3-18-15.2s-1.6-16.7 3.6-23.3c2.1-2.7 3.4-6.1 3.4-9.9 0-6.7-4.2-12.6-10.2-14.9-11.5-4.5-17.7-16.9-14.4-28.8.4-1.3.6-2.8.6-4.3 0-8.8-7.2-16-16-16h-97.5c-12.6 0-25 3.7-35.5 10.7l-61.7 41.1c-11 7.4-25.9 4.4-33.3-6.7s-4.4-25.9 6.7-33.3l61.7-41.1c18.4-12.3 40-18.8 62.1-18.8H384c34.7 0 62.9 27.6 64 62 14.6 11.7 24 29.7 24 50 0 4.5-.5 8.8-1.3 13 15.4 11.7 25.3 30.2 25.3 51 0 6.5-1 12.8-2.8 18.7 11.6 11.8 18.8 27.8 18.8 45.5 0 35.3-28.6 64-64 64h-92.3c4.7 10.4 8.7 21.2 11.8 32.2l5.7 20c10.9 38.2-11.2 78.1-49.4 89zM32 384c-17.7 0-32-14.3-32-32V128c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32v224c0 17.7-14.3 32-32 32H32z"/></svg>',
|
1: '<svg style="fill: var(--text-low-opacity);" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M323.8 477.2c-38.2 10.9-78.1-11.2-89-49.4l-5.7-20c-3.7-13-10.4-25-19.5-35l-51.3-56.4c-8.9-9.8-8.2-25 1.6-33.9s25-8.2 33.9 1.6l51.3 56.4c14.1 15.5 24.4 34 30.1 54.1l5.7 20c3.6 12.7 16.9 20.1 29.7 16.5s20.1-16.9 16.5-29.7l-5.7-20c-5.7-19.9-14.7-38.7-26.6-55.5-5.2-7.3-5.8-16.9-1.7-24.9s12.3-13 21.3-13H448c8.8 0 16-7.2 16-16 0-6.8-4.3-12.7-10.4-15-7.4-2.8-13-9-14.9-16.7s.1-15.8 5.3-21.7c2.5-2.8 4-6.5 4-10.6 0-7.8-5.6-14.3-13-15.7-8.2-1.6-15.1-7.3-18-15.2s-1.6-16.7 3.6-23.3c2.1-2.7 3.4-6.1 3.4-9.9 0-6.7-4.2-12.6-10.2-14.9-11.5-4.5-17.7-16.9-14.4-28.8.4-1.3.6-2.8.6-4.3 0-8.8-7.2-16-16-16h-97.5c-12.6 0-25 3.7-35.5 10.7l-61.7 41.1c-11 7.4-25.9 4.4-33.3-6.7s-4.4-25.9 6.7-33.3l61.7-41.1c18.4-12.3 40-18.8 62.1-18.8H384c34.7 0 62.9 27.6 64 62 14.6 11.7 24 29.7 24 50 0 4.5-.5 8.8-1.3 13 15.4 11.7 25.3 30.2 25.3 51 0 6.5-1 12.8-2.8 18.7 11.6 11.8 18.8 27.8 18.8 45.5 0 35.3-28.6 64-64 64h-92.3c4.7 10.4 8.7 21.2 11.8 32.2l5.7 20c10.9 38.2-11.2 78.1-49.4 89zM32 384c-17.7 0-32-14.3-32-32V128c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32v224c0 17.7-14.3 32-32 32H32z"/></svg>',
|
||||||
2: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M100.5 176c-29 0-52.5 23.5-52.5 52.5V320c0 13.3-10.7 24-24 24S0 333.3 0 320v-91.5C0 173 45 128 100.5 128c29.6 0 57.6 13 76.7 35.6l130.2 153.8c10 11.8 24.6 18.6 40.1 18.6 29 0 52.5-23.5 52.5-52.5V192c0-13.3 10.7-24 24-24s24 10.7 24 24v91.5C448 339 403 384 347.5 384c-29.6 0-57.6-13-76.7-35.6L140.6 194.6c-10-11.8-24.6-18.6-40.1-18.6z"/></svg>',
|
2: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M100.5 176c-29 0-52.5 23.5-52.5 52.5V320c0 13.3-10.7 24-24 24S0 333.3 0 320v-91.5C0 173 45 128 100.5 128c29.6 0 57.6 13 76.7 35.6l130.2 153.8c10 11.8 24.6 18.6 40.1 18.6 29 0 52.5-23.5 52.5-52.5V192c0-13.3 10.7-24 24-24s24 10.7 24 24v91.5C448 339 403 384 347.5 384c-29.6 0-57.6-13-76.7-35.6L140.6 194.6c-10-11.8-24.6-18.6-40.1-18.6z"/></svg>',
|
||||||
|
|
|
@ -58,11 +58,11 @@ function updateColors() {
|
||||||
document.body.setAttribute("style", `--primary: ${colors.text}; --secondary-low-opacity: ${colors.text}22; --background: ${colors.background}; --background-low-opacity: ${colors.background}33; --accent: ${colors.accent}; --accent-low-opacity: ${colors.accent}66; --text: ${colors.text}; --text-low-opacity: ${colors.text}88;`);
|
document.body.setAttribute("style", `--primary: ${colors.text}; --secondary-low-opacity: ${colors.text}22; --background: ${colors.background}; --background-low-opacity: ${colors.background}33; --accent: ${colors.accent}; --accent-low-opacity: ${colors.accent}66; --text: ${colors.text}; --text-low-opacity: ${colors.text}88;`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_list(key) {
|
function get_list(key, hasInput=true) {
|
||||||
let output = [];
|
let output = [];
|
||||||
[...document.querySelectorAll(`#${key} div[id^="${key}-"]`)].forEach((val, index) => {
|
[...document.querySelectorAll(`#${key} div[id^="${key}-"]`)].forEach((val, index) => {
|
||||||
if (!val.classList.contains("bad")) {
|
if (!val.classList.contains("bad")) {
|
||||||
output.push([val.querySelector("input").value, val.querySelector("select").value]);
|
output.push(hasInput ? [val.querySelector("input").value, val.querySelector("select").value] : val.querySelector("select").value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return output;
|
return output;
|
||||||
|
@ -94,6 +94,12 @@ for (const key of Object.keys(socialRegex)) {
|
||||||
}
|
}
|
||||||
socialInput += `</select><input class="bad" oninput="validate_input(this);" data-id="social-%i"></div><svg onclick="dom('social-%i').remove()">${icons.x}</svg>`;
|
socialInput += `</select><input class="bad" oninput="validate_input(this);" data-id="social-%i"></div><svg onclick="dom('social-%i').remove()">${icons.x}</svg>`;
|
||||||
|
|
||||||
|
let flagInput = "<select data-id=\"flags-%i\">";
|
||||||
|
for (const key of Object.keys(flags)) {
|
||||||
|
flagInput += `<option value="${key}">${flags[key]}</option>`
|
||||||
|
}
|
||||||
|
flagInput += `</select><svg onclick="dom('flags-%i').remove()">${icons.x}</svg>`
|
||||||
|
|
||||||
fetch("/api/account/self", {
|
fetch("/api/account/self", {
|
||||||
"method": "GET"
|
"method": "GET"
|
||||||
}).then((response) => (response.json()))
|
}).then((response) => (response.json()))
|
||||||
|
@ -129,7 +135,15 @@ fetch("/api/account/self", {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
inner += `</div><button onclick="add_input('social', '${socialInput.replaceAll("\"", """).replaceAll("\'", "\\\'")}');">Add</button></div></div>`;
|
inner += `</div><button onclick="add_input('social', '${socialInput.replaceAll("\"", """).replaceAll("\'", "\\\'")}');">Add</button></div></div>
|
||||||
|
<div class="added" style="text-align: center;"><div style="text-align: left; margin-bottom: 10px;" id='flags'><h2>Pride Flags</h2>`;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (const flag of (json.flags || [])) {
|
||||||
|
inner += `<div id="social-${i}" data-id="${i}">${flagInput.split("</select")[0].replaceAll("%i", i).replace(`value="${flag}"`, `selected value="${flag}"`)}</select><svg onclick="dom('social-${i}').remove()">${icons.x}</svg></div>`;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
inner += `</div><button onclick="add_input('flags', '${flagInput.replaceAll("\"", """).replaceAll("\'", "\\\'")}');">Add</button></div></div>`
|
||||||
|
|
||||||
x.id = "container";
|
x.id = "container";
|
||||||
x.innerHTML = inner;
|
x.innerHTML = inner;
|
||||||
|
@ -157,6 +171,7 @@ fetch("/api/account/self", {
|
||||||
compliments: get_list("compliments"),
|
compliments: get_list("compliments"),
|
||||||
relationship: get_list("relationship"),
|
relationship: get_list("relationship"),
|
||||||
social: get_list("social"),
|
social: get_list("social"),
|
||||||
|
flags: get_list("flags", false),
|
||||||
public: dom("public").checked
|
public: dom("public").checked
|
||||||
})
|
})
|
||||||
}).then((response) => (response.text()))
|
}).then((response) => (response.text()))
|
||||||
|
|
|
@ -12,23 +12,5 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{TEMPLATE}}
|
{{TEMPLATE}}
|
||||||
|
|
||||||
<div id="key">
|
|
||||||
Key:<br>
|
|
||||||
<span data-icon="4"></span> - Great<br>
|
|
||||||
<span data-icon="3"></span> - Good<br>
|
|
||||||
<span data-icon="2"></span> - Okay<br>
|
|
||||||
<span data-icon="1"></span> - Bad
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
Icons from <a href="https://fontawesome.com" target="_blank">Font Awesome</a>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
[...document.querySelectorAll("[data-icon]")].forEach(function(val, index) {
|
|
||||||
val.innerHTML = icons[val.dataset.icon];
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|