Compare commits
9 Commits
3742749cf6
...
35483c27aa
| Author | SHA1 | Date | |
|---|---|---|---|
|
35483c27aa
|
|||
|
005d2f3b6c
|
|||
|
265e249eaf
|
|||
|
b812e01473
|
|||
|
88f80c38cc
|
|||
|
c70f13d069
|
|||
|
73af2dc3b9
|
|||
|
062cab44bc
|
|||
|
3baccb87b1
|
@@ -23,6 +23,13 @@ Copyright: `© 2017-2020 by Paul James Miller. All rights reserved.`
|
||||
License: SIL Open Font License 1.1
|
||||
Designers: Paul James Miller
|
||||
|
||||
## Atkinson Hyperlegible Mono
|
||||
Affected files: [`data/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf`](./data/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf) [`data/static/fonts/AtkinsonHyperlegibleMono-Italic-VariableFont_wght.ttf`](./data/static/fonts/AtkinsonHyperlegibleMono-Italic-VariableFont_wght.ttf)
|
||||
URL: https://www.brailleinstitute.org/freefont/
|
||||
Copyright: Copyright 2020-2024 The Atkinson Hyperlegible Mono Project Authors (https://github.com/googlefonts/atkinson-hyperlegible-next-mono)
|
||||
License: SIL Open Font License 1.1
|
||||
Designers: Elliott Scott, Megan Eiswerth, Braille Institute, Applied Design Works, Letters From Sweden
|
||||
|
||||
## ICONCINO
|
||||
|
||||
Affected files: [`app/templates/common/icons.html`](./app/templates/common/icons.html)
|
||||
|
||||
@@ -8,6 +8,7 @@ from .constants import (
|
||||
PermissionLevel, permission_level_string,
|
||||
InfoboxKind, InfoboxHTMLClass,
|
||||
REACTION_EMOJI, MOTD_BANNED_TAGS,
|
||||
SIG_BANNED_TAGS, STRICT_BANNED_TAGS,
|
||||
)
|
||||
from .lib.babycode import babycode_to_html, EMOJI, BABYCODE_VERSION
|
||||
from datetime import datetime
|
||||
@@ -148,6 +149,7 @@ def create_app():
|
||||
from app.routes.api import bp as api_bp
|
||||
from app.routes.posts import bp as posts_bp
|
||||
from app.routes.hyperapi import bp as hyperapi_bp
|
||||
from app.routes.guides import bp as guides_bp
|
||||
app.register_blueprint(app_bp)
|
||||
app.register_blueprint(topics_bp)
|
||||
app.register_blueprint(threads_bp)
|
||||
@@ -156,6 +158,7 @@ def create_app():
|
||||
app.register_blueprint(api_bp)
|
||||
app.register_blueprint(posts_bp)
|
||||
app.register_blueprint(hyperapi_bp)
|
||||
app.register_blueprint(guides_bp)
|
||||
|
||||
app.config['SESSION_COOKIE_SECURE'] = True
|
||||
|
||||
@@ -177,6 +180,7 @@ def create_app():
|
||||
"__emoji": EMOJI,
|
||||
"REACTION_EMOJI": REACTION_EMOJI,
|
||||
"MOTD_BANNED_TAGS": MOTD_BANNED_TAGS,
|
||||
"SIG_BANNED_TAGS": SIG_BANNED_TAGS,
|
||||
}
|
||||
|
||||
@app.context_processor
|
||||
@@ -210,6 +214,10 @@ def create_app():
|
||||
def babycode_filter(markup):
|
||||
return babycode_to_html(markup).result
|
||||
|
||||
@app.template_filter('babycode_strict')
|
||||
def babycode_strict_filter(markup):
|
||||
return babycode_to_html(markup, STRICT_BANNED_TAGS).result
|
||||
|
||||
@app.template_filter('extract_h2')
|
||||
def extract_h2(content):
|
||||
import re
|
||||
|
||||
@@ -48,7 +48,16 @@ REACTION_EMOJI = [
|
||||
]
|
||||
|
||||
MOTD_BANNED_TAGS = [
|
||||
'img', 'spoiler', '@mention'
|
||||
'img', 'spoiler', '@mention',
|
||||
]
|
||||
|
||||
SIG_BANNED_TAGS = [
|
||||
'@mention',
|
||||
]
|
||||
|
||||
STRICT_BANNED_TAGS = [
|
||||
'img', 'spoiler', '@mention',
|
||||
'big', 'small', 'center', 'right', 'color',
|
||||
]
|
||||
|
||||
def permission_level_string(perm):
|
||||
|
||||
@@ -28,7 +28,7 @@ class DB:
|
||||
|
||||
if in_transaction:
|
||||
conn.commit()
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
if in_transaction and self._connection:
|
||||
conn.rollback()
|
||||
finally:
|
||||
|
||||
@@ -141,6 +141,12 @@ TAGS = {
|
||||
"spoiler": tag_spoiler,
|
||||
}
|
||||
|
||||
VOID_TAGS = {
|
||||
'lb': lambda attr: '[',
|
||||
'rb': lambda attr: ']',
|
||||
'@': lambda attr: '@',
|
||||
}
|
||||
|
||||
# [img] is considered block for the purposes of collapsing whitespace,
|
||||
# despite being potentially inline (since the resulting <img> tag is inline, but creates a block container around itself and sibling images).
|
||||
# [code] has a special case in is_inline().
|
||||
@@ -252,7 +258,7 @@ def should_collapse(text, surrounding):
|
||||
def sanitize(s):
|
||||
return escape(s.strip().replace('\r\n', '\n').replace('\r', '\n'))
|
||||
|
||||
def babycode_to_html(s, banned_tags={}):
|
||||
def babycode_to_html(s, banned_tags=[]):
|
||||
allowed_tags = set(TAGS.keys())
|
||||
if banned_tags is not None:
|
||||
for tag in banned_tags:
|
||||
@@ -260,6 +266,7 @@ def babycode_to_html(s, banned_tags={}):
|
||||
subj = sanitize(s)
|
||||
parser = Parser(subj)
|
||||
parser.valid_bbcode_tags = allowed_tags
|
||||
parser.void_bbcode_tags = set(VOID_TAGS)
|
||||
parser.bbcode_tags_only_text_children = TEXT_ONLY
|
||||
parser.mentions_allowed = '@mention' not in banned_tags
|
||||
parser.valid_emotes = EMOJI.keys()
|
||||
@@ -296,6 +303,8 @@ def babycode_to_html(s, banned_tags={}):
|
||||
c = c + Markup(fold(child, _nobr, _surrounding))
|
||||
res = TAGS[element['name']](c, element['attr'], surrounding)
|
||||
return res
|
||||
case "bbcode_void":
|
||||
return VOID_TAGS[element['name']](element['attr'])
|
||||
case "link":
|
||||
return f"<a href=\"{element['url']}\">{element['url']}</a>"
|
||||
case 'emote':
|
||||
|
||||
@@ -11,6 +11,7 @@ PAT_MENTION = r'[a-zA-Z0-9_-]'
|
||||
class Parser:
|
||||
def __init__(self, src_str):
|
||||
self.valid_bbcode_tags = {}
|
||||
self.void_bbcode_tags = {}
|
||||
self.valid_emotes = []
|
||||
self.bbcode_tags_only_text_children = []
|
||||
self.mentions_allowed = True
|
||||
@@ -228,11 +229,46 @@ class Parser:
|
||||
}
|
||||
|
||||
|
||||
def parse_bbcode_void(self):
|
||||
self.save_position()
|
||||
|
||||
if not self.check_char("["):
|
||||
self.restore_position()
|
||||
return None
|
||||
|
||||
name = self.match_pattern(PAT_BBCODE_TAG)
|
||||
|
||||
if name == "":
|
||||
self.restore_position()
|
||||
return None
|
||||
|
||||
attr = None
|
||||
|
||||
if self.check_char("="):
|
||||
attr = self.match_pattern(PAT_BBCODE_ATTR)
|
||||
|
||||
if not self.check_char("]"):
|
||||
self.restore_position()
|
||||
return None
|
||||
|
||||
if not name in self.void_bbcode_tags:
|
||||
self.restore_position()
|
||||
return None
|
||||
|
||||
self.forget_position()
|
||||
return {
|
||||
'type': 'bbcode_void',
|
||||
'name': name,
|
||||
'attr': attr,
|
||||
}
|
||||
|
||||
|
||||
def parse_element(self, siblings):
|
||||
if self.is_end_of_source():
|
||||
return None
|
||||
|
||||
element = self.parse_emote() \
|
||||
or self.parse_bbcode_void() \
|
||||
or self.parse_bbcode() \
|
||||
or self.parse_rule() \
|
||||
or self.parse_link() \
|
||||
|
||||
@@ -217,7 +217,7 @@ def bookmark_thread(thread_id):
|
||||
@bp.get('/current-user')
|
||||
def get_current_user_info():
|
||||
if not is_logged_in():
|
||||
return {'user': null}
|
||||
return {'user': None}
|
||||
|
||||
user = get_active_user()
|
||||
return {
|
||||
|
||||
@@ -5,8 +5,3 @@ bp = Blueprint("app", __name__, url_prefix = "/")
|
||||
@bp.route("/")
|
||||
def index():
|
||||
return redirect(url_for("topics.all_topics"))
|
||||
|
||||
|
||||
@bp.route("/babycode")
|
||||
def babycode_guide():
|
||||
return render_template('babycode.html')
|
||||
|
||||
13
app/routes/guides.py
Normal file
13
app/routes/guides.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
bp = Blueprint('guides', __name__, url_prefix='/guides/')
|
||||
|
||||
|
||||
@bp.get('/babycode')
|
||||
def babycode():
|
||||
return render_template('guides/babycode.html')
|
||||
|
||||
|
||||
@bp.get('/contact')
|
||||
def contact():
|
||||
return render_template('guides/contact.html')
|
||||
@@ -10,7 +10,7 @@ from ..models import (
|
||||
BookmarkCollections, BookmarkedThreads,
|
||||
Mentions, PostHistory,
|
||||
)
|
||||
from ..constants import InfoboxKind, PermissionLevel
|
||||
from ..constants import InfoboxKind, PermissionLevel, SIG_BANNED_TAGS
|
||||
from ..auth import digest, verify
|
||||
from wand.image import Image
|
||||
from wand.exceptions import WandException
|
||||
@@ -67,11 +67,22 @@ def get_active_user():
|
||||
|
||||
|
||||
def create_session(user_id):
|
||||
return Sessions.create({
|
||||
"key": secrets.token_hex(16),
|
||||
print('key')
|
||||
key = secrets.token_hex(16)
|
||||
print(key)
|
||||
print('user id')
|
||||
print(user_id)
|
||||
print('expires')
|
||||
expires_at = int(time.time()) + 31 * 24 * 60 * 60
|
||||
print(expires_at)
|
||||
print('create')
|
||||
s = Sessions.create({
|
||||
"key": key,
|
||||
"user_id": user_id,
|
||||
"expires_at": int(time.time()) + 31 * 24 * 60 * 60,
|
||||
"expires_at": expires_at,
|
||||
})
|
||||
print(s)
|
||||
return s
|
||||
|
||||
|
||||
def extend_session(user_id):
|
||||
@@ -334,26 +345,27 @@ def sign_up_post():
|
||||
else:
|
||||
display_name = ''
|
||||
|
||||
new_user = Users.create({
|
||||
"username": username,
|
||||
'display_name': display_name,
|
||||
"password_hash": hashed,
|
||||
"permission": PermissionLevel.GUEST.value,
|
||||
})
|
||||
|
||||
BookmarkCollections.create_default(new_user.id)
|
||||
|
||||
if current_app.config['DISABLE_SIGNUP']:
|
||||
invite_key = InviteKeys.find({'key': key})
|
||||
new_user.update({
|
||||
'invited_by': invite_key.created_by,
|
||||
'permission': PermissionLevel.USER.value,
|
||||
with db.transaction():
|
||||
new_user = Users.create({
|
||||
"username": username.lower(),
|
||||
'display_name': display_name,
|
||||
"password_hash": hashed,
|
||||
"permission": PermissionLevel.GUEST.value,
|
||||
})
|
||||
invite_key.delete()
|
||||
|
||||
session_obj = create_session(new_user.id)
|
||||
BookmarkCollections.create_default(new_user.id)
|
||||
|
||||
session['pyrom_session_key'] = session_obj.key
|
||||
if current_app.config['DISABLE_SIGNUP']:
|
||||
invite_key = InviteKeys.find({'key': key})
|
||||
new_user.update({
|
||||
'invited_by': invite_key.created_by,
|
||||
'permission': PermissionLevel.USER.value,
|
||||
})
|
||||
invite_key.delete()
|
||||
|
||||
session_obj = create_session(new_user.id)
|
||||
|
||||
session['pyrom_session_key'] = session_obj.key
|
||||
flash("Signed up successfully!", InfoboxKind.INFO)
|
||||
return redirect(url_for("topics.all_topics"))
|
||||
|
||||
@@ -392,7 +404,7 @@ def settings_form(username):
|
||||
status = request.form.get('status', default="")[:100]
|
||||
original_sig = request.form.get('signature', default='').strip()
|
||||
if original_sig:
|
||||
rendered_sig = babycode_to_html(original_sig).result
|
||||
rendered_sig = babycode_to_html(original_sig, SIG_BANNED_TAGS).result
|
||||
else:
|
||||
rendered_sig = ''
|
||||
session['subscribe_by_default'] = request.form.get('subscribe_by_default', default='off') == 'on'
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
<!-- kate: remove-trailing-space off; -->
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}babycode guide{% endblock %}
|
||||
{% block content %}
|
||||
<div class=darkbg>
|
||||
<h1 class="thread-title">Babycode guide</h1>
|
||||
</div>
|
||||
<div class="babycode-guide-container">
|
||||
<div class="guide-topics">
|
||||
{% set sections %}
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="what-is-babycode">What is babycode?</h2>
|
||||
<p>You may be familiar with BBCode, a loosely related family of markup languages popular on forums. Babycode is another, simplified, dialect of those languages. It is a way of formatting text by enclosing parts of it in special tags.</p>
|
||||
<p>A <b>tag</b> is a short name enclosed in square brackets. Tags can be opening tags, like <code class="inline-code">[b]</code> or closing tags, like <code class="inline-code">[/b]</code>. Anything inserted between matching opening and closing tags is known as the tag's content.</p>
|
||||
<p>Some tags can provide more specific instructions using an <b>attribute</b>. An attribute is added to the opening tag with an equals sign (<code class="inline-code">=</code>). This allows you to specify details like a particular color or a link's address.</p>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="text-formatting-tags">Text formatting tags</h2>
|
||||
<ul class='babycode-guide-list'>
|
||||
<li>To make some text <strong>bold</strong>, enclose it in <code class="inline-code">[b][/b]</code>:<br>
|
||||
[b]Hello World[/b]<br>
|
||||
Will become<br>
|
||||
<strong>Hello World</strong>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='babycode-guide-list'>
|
||||
<li>To <em>italicize</em> text, enclose it in <code class="inline-code">[i][/i]</code>:<br>
|
||||
[i]Hello World[/i]<br>
|
||||
Will become<br>
|
||||
<em>Hello World</em>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='babycode-guide-list'>
|
||||
<li>To make some text <del>strikethrough</del>, enclose it in <code class="inline-code">[s][/s]</code>:<br>
|
||||
[s]Hello World[/s]<br>
|
||||
Will become<br>
|
||||
<del>Hello World</del>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='babycode-guide-list'>
|
||||
<li>To <u>underline</u> some text, enclose it in <code class="inline-code">[u][/u]</code>:<br>
|
||||
[u]Hello World[/u]<br>
|
||||
Will become<br>
|
||||
<u>Hello World</u>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='babycode-guide-list'>
|
||||
<li>To make some text {{ "[big]big[/big]" | babycode | safe }}, enclose it in <code class="inline-code">[big][/big]</code>:<br>
|
||||
[big]Hello World[/big]<br>
|
||||
Will become<br>
|
||||
{{ "[big]Hello World[/big]" | babycode | safe }}
|
||||
<li>Similarly, you can make text {{ "[small]small[/small]" | babycode | safe }} with <code class="inline-code">[small][/small]</code>:<br>
|
||||
[small]Hello World[/small]<br>
|
||||
Will become<br>
|
||||
{{ "[small]Hello World[/small]" | babycode | safe }}
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='babycode-guide-list'>
|
||||
<li>You can change the text color by using <code class="inline-code">[color][/color]</code>:<br>
|
||||
[color=red]Red text[/color]<br>
|
||||
[color=white]White text[/color]<br>
|
||||
[color=#3b08f0]Blueish text[/color]<br>
|
||||
Will become<br>
|
||||
{{ "[color=red]Red text[/color]" | babycode | safe }}<br>
|
||||
{{ "[color=white]White text[/color]" | babycode | safe }}<br>
|
||||
{{ "[color=#3b08f0]Blueish text[/color]" | babycode | safe }}<br>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='babycode-guide-list'>
|
||||
<li>You can center text by enclosing it in <code class="inline-code">[center][/center]</code>:<br>
|
||||
[center]Hello World[/center]<br>
|
||||
Will become<br>
|
||||
{{ "[center]Hello World[/center]" | babycode | safe }}
|
||||
</li>
|
||||
<li>You can right-align text by enclosing it in <code class="inline-code">[right][/right]</code>:<br>
|
||||
[right]Hello World[/right]<br>
|
||||
Will become<br>
|
||||
{{ "[right]Hello World[/right]" | babycode | safe }}
|
||||
</li>
|
||||
Note: the center and right tags will break the paragraph. See <a href="#paragraph-rules">Paragraph rules</a> for more details.
|
||||
</ul>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="emoji">Emoji</h2>
|
||||
<p>There are a few emoji in the style of old forum emotes:</p>
|
||||
<table class="emoji-table">
|
||||
<tr>
|
||||
<th>Short code</th>
|
||||
<th>Emoji result</th>
|
||||
</tr>
|
||||
{% for emoji in __emoji %}
|
||||
<tr>
|
||||
<td>{{ ("[code]:%s:[/code]" % emoji) | babycode | safe }}</td>
|
||||
<td>{{ __emoji[emoji] | safe }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<p>Special thanks to the <a href="https://gh.vercte.net/forumoji/">Forumoji project</a> and its contributors for these graphics.</p>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="paragraph-rules">Paragraph rules</h2>
|
||||
<p>Line breaks in babycode work like Markdown: to start a new paragraph, use two line breaks:</p>
|
||||
{{ '[code]paragraph 1\n\nparagraph 2[/code]' | babycode | safe }}
|
||||
Will produce:<br>
|
||||
{{ 'paragraph 1\n\nparagraph 2' | babycode | safe }}
|
||||
<p>To break a line without starting a new paragraph, end a line with two spaces:</p>
|
||||
{{ '[code]paragraph 1 \nstill paragraph 1[/code]' | babycode | safe }}
|
||||
That will produce:<br>
|
||||
{{ 'paragraph 1 \nstill paragraph 1' | babycode | safe }}
|
||||
<p>Additionally, the following tags will break into a new paragraph:</p>
|
||||
<ul>
|
||||
<li><code class="inline-code">[code]</code> (code block, not inline);</li>
|
||||
<li><code class="inline-code">[img]</code>;</li>
|
||||
<li><code class="inline-code">[center]</code>;</li>
|
||||
<li><code class="inline-code">[right]</code>;</li>
|
||||
<li><code class="inline-code">[ul]</code> and <code class="inline-code">[ol]</code>;</li>
|
||||
<li><code class="inline-code">[quote]</code>.</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="links">Links</h2>
|
||||
<p>Loose links (starting with http:// or https://) will automatically get converted to clickable links. To add a label to a link, use<br><code class="inline-code">[url=https://example.com]Link label[/url]</code>:<br>
|
||||
<a href="https://example.com">Link label</a></p>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="attaching-an-image">Attaching an image</h2>
|
||||
<p>To add an image to your post, use the <code class="inline-code">[img]</code> tag:<br>
|
||||
<code class="inline-code">[img=https://forum.poto.cafe/avatars/default.webp]the Python logo with a cowboy hat[/img]</code>
|
||||
{{ '[img=/static/avatars/default.webp]the Python logo with a cowboy hat[/img]' | babycode | safe }}
|
||||
</p>
|
||||
<p>The attribute is the image URL. The text inside the tag will become the image's alt text.</p>
|
||||
<p>Images will always break up a paragraph and will get scaled down to a maximum of 400px. However, consecutive image tags will try to stay in one line, wrapping if necessary. Break the paragraph if you wish to keep images on their own paragraph.</p>
|
||||
<p>Multiple images attached to a post can be clicked to open a dialog to view them.</p>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="adding-code-blocks">Adding code blocks</h2>
|
||||
{% set code = 'func _ready() -> void:\n\tprint("hello world!")' %}
|
||||
<p>There are two kinds of code blocks recognized by babycode: inline and block. Inline code blocks do not break a paragraph. They can be added with <code class="inline-code">[code]your code here[/code]</code>. As long as there are no line breaks inside the code block, it is considered inline. If there are any, it will produce this:</p>
|
||||
{{ ('[code]%s[/code]' % code) | babycode | safe }}
|
||||
<p>Optionally, you can enable syntax highlighting by specifying the language in the attribute like this: <code class="inline-code">[code=gdscript]</code></p>
|
||||
{{ ('[code=gdscript]%s[/code]' % code) | babycode | safe}}
|
||||
<p>A full list of languages that can be highlighted is available <a href="https://pygments.org/languages/" target=_blank>here</a> (the short names column).</p>
|
||||
<p>Inline code tags look like this: {{ '[code]Inline code[/code]' | babycode | safe }}</p>
|
||||
<p>Babycodes are not parsed inside code blocks.</p>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="quoting">Quoting</h2>
|
||||
<p>Text enclosed within <code class="inline-code">[quote][/quote]</code> will look like a quote:</p>
|
||||
<blockquote>A man provided with paper, pencil, and rubber, and subject to strict discipline, is in effect a universal machine.</blockquote>
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="lists">Lists</h2>
|
||||
{% set list = '[ul]\nitem 1\n\nitem 2\n\nitem 3 \nstill item 3 (break line without inserting a new item by using two spaces at the end of a line)\n[/ul]' %}
|
||||
<p>There are two kinds of lists, ordered (1, 2, 3, ...) and unordered (bullet points). Ordered lists are made with <code class="inline-code">[ol][/ol]</code> tags, and unordered with <code class="inline-code">[ul][/ul]</code>. Every new paragraph according to the <a href="#paragraph-rules">usual paragraph rules</a> will create a new list item. For example:</p>
|
||||
{{ ('[code]%s[/code]' % list) | babycode | safe }}
|
||||
Will produce the following list:
|
||||
{{ list | babycode | safe }}
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="spoilers">Spoilers</h2>
|
||||
{% set spoiler = "[spoiler=Major Metal Gear Spoilers]Snake dies[/spoiler]" %}
|
||||
<p>You can make a section collapsible by using the <code class="inline-code">[spoiler]</code> tag:</p>
|
||||
{{ ("[code]\n%s[/code]" % spoiler) | babycode | safe }}
|
||||
Will produce:
|
||||
{{ spoiler | babycode | safe }}
|
||||
All other tags are supported inside spoilers.
|
||||
</section>
|
||||
<section class="babycode-guide-section">
|
||||
<h2 id="mentions">Mentioning users</h2>
|
||||
<p>You can mention users by their username (<em>not</em> their display name) by using <code class="inline-code">@username</code>. A user's username is always shown below their avatar and display name on their posts and their user page.</p>
|
||||
<p>A mention will show up on your post as a clickable box with the user's display name if they have one set or their username with an <code class="inline-code">@</code> symbol if they don't:</p>
|
||||
<a class="mention" href="#mentions" title="@user-without-display-name">@user-without-display-name</a>
|
||||
<a class="mention display" href="#mentions" title="@user-with-display-name">User with display name</a>
|
||||
<a class="mention display me" href="#mentions" title="@your-username">Your display name</a>
|
||||
<p>Mentioning a user does not notify them. It is simply a way to link to their profile in your posts.</p>
|
||||
</section>
|
||||
{% endset %}
|
||||
{{ sections | safe }}
|
||||
</div>
|
||||
<div class="guide-toc">
|
||||
<h2>Table of contents</h2>
|
||||
{% set toc = sections | extract_h2 %}
|
||||
<ul>
|
||||
{% for heading in toc %}
|
||||
<li><a href='#{{ heading.id }}'>{{ heading.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -23,9 +23,7 @@
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% block content %}{% endblock %}
|
||||
<footer class="darkbg">
|
||||
<span>Pyrom commit <a href="{{ "https://git.poto.cafe/yagich/pyrom/commit/" + __commit }}">{{ __commit[:8] }}</a></span>
|
||||
</footer>
|
||||
{% include 'common/footer.html' %}
|
||||
</bitty-6-0>
|
||||
<script src="{{ "/static/js/ui.js" | cachebust }}"></script>
|
||||
</body>
|
||||
|
||||
6
app/templates/common/footer.html
Normal file
6
app/templates/common/footer.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<footer id="footer">
|
||||
<span>Pyrom commit <a href="{{ "https://git.poto.cafe/yagich/pyrom/commit/" + __commit }}">{{ __commit[:8] }}</a></span>
|
||||
<ul class="horizontal">
|
||||
<li><a href="{{ url_for('guides.contact') }}">Contact</a></li>
|
||||
</ul>
|
||||
</footer>
|
||||
@@ -99,7 +99,7 @@
|
||||
<button data-send="insertBabycodeTag" data-tag="spoiler=" data-break-line="1" data-prefill="hidden content" class="babycode-button contain-svg" type=button id="post-editor-spoiler" title="Insert spoiler" {{"disabled" if "spoiler" in banned_tags else ""}}>{{ icn_spoiler() }}</button>
|
||||
</span>
|
||||
<textarea class="babycode-editor" name="{{ ta_name }}" id="babycode-content" placeholder="{{ ta_placeholder }}" {{ "required" if not optional else "" }} autocomplete="off" data-receive="insertBabycodeTag addQuote">{{ prefill }}</textarea>
|
||||
<a href="{{ url_for("app.babycode_guide") }}" target="_blank">babycode guide</a>
|
||||
<a href="{{ url_for("guides.babycode") }}" target="_blank">babycode guide</a>
|
||||
{% if banned_tags %}
|
||||
<div>Forbidden tags:</div>
|
||||
<div>
|
||||
@@ -287,3 +287,21 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro guide_sections() %}
|
||||
<div class="guide-container">
|
||||
<div class="guide-topics">
|
||||
{% set sections %}{{ caller() }}{% endset %}
|
||||
{{ sections | safe }}
|
||||
</div>
|
||||
<div class="guide-toc">
|
||||
<h2>Table of contents</h2>
|
||||
{% set toc = sections | extract_h2 %}
|
||||
<ul>
|
||||
{% for heading in toc %}
|
||||
<li><a href='#{{ heading.id }}'>{{ heading.text }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
190
app/templates/guides/babycode.html
Normal file
190
app/templates/guides/babycode.html
Normal file
@@ -0,0 +1,190 @@
|
||||
{% extends 'base.html' %}
|
||||
{% from 'common/macros.html' import guide_sections with context %}
|
||||
{% block title %}babycode guide{% endblock %}
|
||||
{% block content %}
|
||||
<div class=darkbg>
|
||||
<h1 class="thread-title">Babycode guide</h1>
|
||||
</div>
|
||||
|
||||
{% call() guide_sections() %}
|
||||
<section class="guide-section">
|
||||
<h2 id="what-is-babycode">What is babycode?</h2>
|
||||
<p>You may be familiar with BBCode, a loosely related family of markup languages popular on forums. Babycode is another, simplified, dialect of those languages. It is a way of formatting text by enclosing parts of it in special tags.</p>
|
||||
<p>A <b>tag</b> is a short name enclosed in square brackets. Tags can be opening tags, like <code class="inline-code">[b]</code> or closing tags, like <code class="inline-code">[/b]</code>. Anything inserted between matching opening and closing tags is known as the tag's content.</p>
|
||||
<p>Some tags can provide more specific instructions using an <b>attribute</b>. An attribute is added to the opening tag with an equals sign (<code class="inline-code">=</code>). This allows you to specify details like a particular color or a link's address.</p>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="text-formatting-tags">Text formatting tags</h2>
|
||||
<ul class='guide-list'>
|
||||
<li>To make some text <strong>bold</strong>, enclose it in <code class="inline-code">[b][/b]</code>:<br>
|
||||
[b]Hello World[/b]<br>
|
||||
Will become<br>
|
||||
<strong>Hello World</strong>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='guide-list'>
|
||||
<li>To <em>italicize</em> text, enclose it in <code class="inline-code">[i][/i]</code>:<br>
|
||||
[i]Hello World[/i]<br>
|
||||
Will become<br>
|
||||
<em>Hello World</em>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='guide-list'>
|
||||
<li>To make some text <del>strikethrough</del>, enclose it in <code class="inline-code">[s][/s]</code>:<br>
|
||||
[s]Hello World[/s]<br>
|
||||
Will become<br>
|
||||
<del>Hello World</del>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='guide-list'>
|
||||
<li>To <u>underline</u> some text, enclose it in <code class="inline-code">[u][/u]</code>:<br>
|
||||
[u]Hello World[/u]<br>
|
||||
Will become<br>
|
||||
<u>Hello World</u>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='guide-list'>
|
||||
<li>To make some text {{ "[big]big[/big]" | babycode | safe }}, enclose it in <code class="inline-code">[big][/big]</code>:<br>
|
||||
[big]Hello World[/big]<br>
|
||||
Will become<br>
|
||||
{{ "[big]Hello World[/big]" | babycode | safe }}
|
||||
<li>Similarly, you can make text {{ "[small]small[/small]" | babycode | safe }} with <code class="inline-code">[small][/small]</code>:<br>
|
||||
[small]Hello World[/small]<br>
|
||||
Will become<br>
|
||||
{{ "[small]Hello World[/small]" | babycode | safe }}
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='guide-list'>
|
||||
<li>You can change the text color by using <code class="inline-code">[color][/color]</code>:<br>
|
||||
[color=red]Red text[/color]<br>
|
||||
[color=white]White text[/color]<br>
|
||||
[color=#3b08f0]Blueish text[/color]<br>
|
||||
Will become<br>
|
||||
{{ "[color=red]Red text[/color]" | babycode | safe }}<br>
|
||||
{{ "[color=white]White text[/color]" | babycode | safe }}<br>
|
||||
{{ "[color=#3b08f0]Blueish text[/color]" | babycode | safe }}<br>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='guide-list'>
|
||||
<li>You can center text by enclosing it in <code class="inline-code">[center][/center]</code>:<br>
|
||||
[center]Hello World[/center]<br>
|
||||
Will become<br>
|
||||
{{ "[center]Hello World[/center]" | babycode | safe }}
|
||||
</li>
|
||||
<li>You can right-align text by enclosing it in <code class="inline-code">[right][/right]</code>:<br>
|
||||
[right]Hello World[/right]<br>
|
||||
Will become<br>
|
||||
{{ "[right]Hello World[/right]" | babycode | safe }}
|
||||
</li>
|
||||
Note: the center and right tags will break the paragraph. See <a href="#paragraph-rules">Paragraph rules</a> for more details.
|
||||
</ul>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="emoji">Emoji</h2>
|
||||
<p>There are a few emoji in the style of old forum emotes:</p>
|
||||
<table class="emoji-table">
|
||||
<tr>
|
||||
<th>Short code</th>
|
||||
<th>Emoji result</th>
|
||||
</tr>
|
||||
{% for emoji in __emoji %}
|
||||
<tr>
|
||||
<td>{{ ("[code]:%s:[/code]" % emoji) | babycode | safe }}</td>
|
||||
<td>{{ __emoji[emoji] | safe }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<p>Special thanks to the <a href="https://gh.vercte.net/forumoji/">Forumoji project</a> and its contributors for these graphics.</p>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="paragraph-rules">Paragraph rules</h2>
|
||||
<p>Line breaks in babycode work like Markdown: to start a new paragraph, use two line breaks:</p>
|
||||
{{ '[code]paragraph 1\n\nparagraph 2[/code]' | babycode | safe }}
|
||||
Will produce:<br>
|
||||
{{ 'paragraph 1\n\nparagraph 2' | babycode | safe }}
|
||||
<p>To break a line without starting a new paragraph, end a line with two spaces:</p>
|
||||
{{ '[code]paragraph 1 \nstill paragraph 1[/code]' | babycode | safe }}
|
||||
That will produce:<br>
|
||||
{{ 'paragraph 1 \nstill paragraph 1' | babycode | safe }}
|
||||
<p>Additionally, the following tags will break into a new paragraph:</p>
|
||||
<ul>
|
||||
<li><code class="inline-code">[code]</code> (code block, not inline);</li>
|
||||
<li><code class="inline-code">[img]</code>;</li>
|
||||
<li><code class="inline-code">[center]</code>;</li>
|
||||
<li><code class="inline-code">[right]</code>;</li>
|
||||
<li><code class="inline-code">[ul]</code> and <code class="inline-code">[ol]</code>;</li>
|
||||
<li><code class="inline-code">[quote]</code>.</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="links">Links</h2>
|
||||
<p>Loose links (starting with http:// or https://) will automatically get converted to clickable links. To add a label to a link, use<br><code class="inline-code">[url=https://example.com]Link label[/url]</code>:<br>
|
||||
<a href="https://example.com">Link label</a></p>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="attaching-an-image">Attaching an image</h2>
|
||||
<p>To add an image to your post, use the <code class="inline-code">[img]</code> tag:<br>
|
||||
<code class="inline-code">[img=https://forum.poto.cafe/avatars/default.webp]the Python logo with a cowboy hat[/img]</code>
|
||||
{{ '[img=/static/avatars/default.webp]the Python logo with a cowboy hat[/img]' | babycode | safe }}
|
||||
</p>
|
||||
<p>The attribute is the image URL. The text inside the tag will become the image's alt text.</p>
|
||||
<p>Images will always break up a paragraph and will get scaled down to a maximum of 400px. However, consecutive image tags will try to stay in one line, wrapping if necessary. Break the paragraph if you wish to keep images on their own paragraph.</p>
|
||||
<p>Multiple images attached to a post can be clicked to open a dialog to view them.</p>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="adding-code-blocks">Adding code blocks</h2>
|
||||
{% set code = 'func _ready() -> void:\n\tprint("hello world!")' %}
|
||||
<p>There are two kinds of code blocks recognized by babycode: inline and block. Inline code blocks do not break a paragraph. They can be added with <code class="inline-code">[code]your code here[/code]</code>. As long as there are no line breaks inside the code block, it is considered inline. If there are any, it will produce this:</p>
|
||||
{{ ('[code]%s[/code]' % code) | babycode | safe }}
|
||||
<p>Optionally, you can enable syntax highlighting by specifying the language in the attribute like this: <code class="inline-code">[code=gdscript]</code></p>
|
||||
{{ ('[code=gdscript]%s[/code]' % code) | babycode | safe}}
|
||||
<p>A full list of languages that can be highlighted is available <a href="https://pygments.org/languages/" target=_blank>here</a> (the short names column).</p>
|
||||
<p>Inline code tags look like this: {{ '[code]Inline code[/code]' | babycode | safe }}</p>
|
||||
<p>Babycodes are not parsed inside code blocks.</p>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="quoting">Quoting</h2>
|
||||
<p>Text enclosed within <code class="inline-code">[quote][/quote]</code> will look like a quote:</p>
|
||||
<blockquote>A man provided with paper, pencil, and rubber, and subject to strict discipline, is in effect a universal machine.</blockquote>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="lists">Lists</h2>
|
||||
{% set list = '[ul]\nitem 1\n\nitem 2\n\nitem 3 \nstill item 3 (break line without inserting a new item by using two spaces at the end of a line)\n[/ul]' %}
|
||||
<p>There are two kinds of lists, ordered (1, 2, 3, ...) and unordered (bullet points). Ordered lists are made with <code class="inline-code">[ol][/ol]</code> tags, and unordered with <code class="inline-code">[ul][/ul]</code>. Every new paragraph according to the <a href="#paragraph-rules">usual paragraph rules</a> will create a new list item. For example:</p>
|
||||
{{ ('[code]%s[/code]' % list) | babycode | safe }}
|
||||
Will produce the following list:
|
||||
{{ list | babycode | safe }}
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="spoilers">Spoilers</h2>
|
||||
{% set spoiler = "[spoiler=Major Metal Gear Spoilers]Snake dies[/spoiler]" %}
|
||||
<p>You can make a section collapsible by using the <code class="inline-code">[spoiler]</code> tag:</p>
|
||||
{{ ("[code]\n%s[/code]" % spoiler) | babycode | safe }}
|
||||
Will produce:
|
||||
{{ spoiler | babycode | safe }}
|
||||
All other tags are supported inside spoilers.
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="mentions">Mentioning users</h2>
|
||||
<p>You can mention users by their username (<em>not</em> their display name) by using <code class="inline-code">@username</code>. A user's username is always shown below their avatar and display name on their posts and their user page.</p>
|
||||
<p>A mention will show up on your post as a clickable box with the user's display name if they have one set or their username with an <code class="inline-code">@</code> symbol if they don't:</p>
|
||||
<a class="mention" href="#mentions" title="@user-without-display-name">@user-without-display-name</a>
|
||||
<a class="mention display" href="#mentions" title="@user-with-display-name">User with display name</a>
|
||||
<a class="mention display me" href="#mentions" title="@your-username">Your display name</a>
|
||||
<p>Mentioning a user does not notify them. It is simply a way to link to their profile in your posts.</p>
|
||||
</section>
|
||||
<section class="guide-section">
|
||||
<h2 id="void-tags">Void tags</h2>
|
||||
<p>The special void tags <code class="inline-code">[lb]</code>, <code class="inline-code">[rb]</code>, and <code class="inline-code">[@]</code> will appear as the literal characters <code class="inline-code">[</code>, <code class="inline-code">]</code>, and <code class="inline-code">@</code> respectively. Unlike other tags, they are self-contained and have no closing equivalent.</p>
|
||||
<ul class="guide-list">
|
||||
{% set lbrb = "[color=red]This text will be red[/color]\n\n[lb]color=red[rb]This text won't be red[lb]/color[rb]" %}
|
||||
<li><code class="inline-code">[lb]</code> and <code class="inline-code">[rb]</code> allow you to use square brackets without them being interpreted as Babycode:
|
||||
{{ ("[code]" + lbrb + "[/code]") | babycode | safe }}
|
||||
Will result in:<br>
|
||||
{{ lbrb | babycode | safe }}
|
||||
</li>
|
||||
<li>The <code class="inline-code">[@]</code> tag allows you to use the @ symbol without it being turned into a mention.</li>
|
||||
</ul>
|
||||
</section>
|
||||
{% endcall %}
|
||||
{% endblock %}
|
||||
13
app/templates/guides/contact.html
Normal file
13
app/templates/guides/contact.html
Normal file
@@ -0,0 +1,13 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}contact us{% endblock %}
|
||||
{% block content %}
|
||||
<div class="darkbg settings-container">
|
||||
<h1>Contact</h1>
|
||||
{% if config.ADMIN_CONTACT_INFO %}
|
||||
<p>The administrators of {{ config.SITE_NAME }} provide the following contact information:</p>
|
||||
<div>{{ config.ADMIN_CONTACT_INFO | babycode_strict | safe }}</div>
|
||||
{% else %}
|
||||
<p>The administrators of {{ config.SITE_NAME }} did not provide any contact information.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="darkbg login-container">
|
||||
<h1>Confirm account deletion</h1>
|
||||
<p>Are you sure you want to delete your account on {{ config.SITE_NAME }}? <strong>This action is irreversible.</strong> Your posts and threads will remain accessible to preserve history but will be de-personalized, showing up as authored by a system user. Posts that @mention you will also mention the system user instead.</p>
|
||||
<p>If you wish for any and all content relating to you to be removed, you will have to ask {{ config.SITE_NAME }}'s administrators separately.</p>
|
||||
<p>If you wish for any and all content relating to you to be removed, you will have to <a href="{{url_for("guides.contact")}}" target="_blank">contact {{ config.SITE_NAME }}'s administrators separately.</a></p>
|
||||
<p>If you are sure, please confirm your current password below.</p>
|
||||
<form method="post">
|
||||
<label for="password">Confirm password</label>
|
||||
|
||||
@@ -5,44 +5,55 @@
|
||||
{% set disable_avatar = not is_logged_in() %}
|
||||
<div class='darkbg settings-container'>
|
||||
<h1>User settings</h1>
|
||||
<form class='avatar-form' method='post' action='{{ url_for('users.set_avatar', username=active_user.username) }}' enctype='multipart/form-data'>
|
||||
<span>Set avatar (1mb max)</span>
|
||||
<img src='{{ active_user.get_avatar_url() }}'>
|
||||
<input id='file' type='file' name='avatar' accept='image/*' required>
|
||||
<div>
|
||||
<input type='submit' value='Upload avatar' {{ 'disabled' if disable_avatar else '' }}>
|
||||
<input type='submit' value='Clear avatar' formaction='{{ url_for('users.clear_avatar', username=active_user.username) }}' formnovalidate {{ 'disabled' if active_user.is_default_avatar() else '' }}>
|
||||
</div>
|
||||
</form>
|
||||
<form method='post'>
|
||||
<label for='theme'>Theme (beta)</label>
|
||||
<select autocomplete='off' id='theme' name='theme'>
|
||||
{% for theme in config.allowed_themes %}
|
||||
<option value="{{ theme }}" {{ 'selected' if get_prefers_theme() == theme }}>{{ theme | theme_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for='topic_sort_by'>Sort threads by:</label>
|
||||
<select id='topic_sort_by' name='topic_sort_by'>
|
||||
<option value='activity' {{ 'selected' if session['sort_by'] == 'activity' else '' }}>Latest activity</option>
|
||||
<option value='thread' {{ 'selected' if session['sort_by'] == 'thread' else '' }}>Thread creation date</option>
|
||||
</select>
|
||||
<label for='display_name'>Display name</label>
|
||||
<input type='text' id='display_name' name='display_name' value='{{ active_user.display_name }}' pattern="(?:[\w!#$%^*\(\)\-_=+\[\]\{\}\|;:,.?\s]{3,50})?" title='3-50 characters, no @, no <>, no &' placeholder='Optional. Will be shown in place of username.' autocomplete='off'></input>
|
||||
<label for='status'>Status</label>
|
||||
<input type='text' id='status' name='status' value='{{ active_user.status }}' maxlength=100 placeholder='Will be shown under your name. Max 100 characters.'>
|
||||
<label for='babycode-content'>Signature</label>
|
||||
{{ babycode_editor_component(ta_name='signature', prefill=active_user.signature_original_markup, ta_placeholder='Will be shown under each of your posts', optional=true) }}
|
||||
<input autocomplete='off' type='checkbox' id='subscribe_by_default' name='subscribe_by_default' {{ 'checked' if session.get('subscribe_by_default', default=true) else '' }}>
|
||||
<label for='subscribe_by_default'>Subscribe to thread by default when responding</label><br>
|
||||
<input type='submit' value='Save settings'>
|
||||
</form>
|
||||
<form method='post' action='{{ url_for('users.change_password', username=active_user.username) }}'>
|
||||
<label for="new_password">Change password</label><br>
|
||||
<input type="password" id="new_password" name="new_password" pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_])(?!.*\s).{10,}" title="10+ chars with: 1 uppercase, 1 lowercase, 1 number, 1 special char, and no spaces" required autocomplete="new-password"><br>
|
||||
<label for="new_password2">Confirm new password</label><br>
|
||||
<input type="password" id="new_password2" name="new_password2" pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_])(?!.*\s).{10,}" title="10+ chars with: 1 uppercase, 1 lowercase, 1 number, 1 special char, and no spaces" required autocomplete="new-password"><br>
|
||||
<input class="warn" type="submit" value="Change password">
|
||||
</form>
|
||||
<div class="settings-grid">
|
||||
<fieldset class="hfc">
|
||||
<legend>Set avatar</legend>
|
||||
<form class='avatar-form' method='post' action='{{ url_for('users.set_avatar', username=active_user.username) }}' enctype='multipart/form-data'>
|
||||
<img src='{{ active_user.get_avatar_url() }}'>
|
||||
<input id='file' type='file' name='avatar' accept='image/*' required>
|
||||
<div>
|
||||
<input type='submit' value='Save avatar' {{ 'disabled' if disable_avatar else '' }}>
|
||||
<input type='submit' value='Clear avatar' formaction='{{ url_for('users.clear_avatar', username=active_user.username) }}' formnovalidate {{ 'disabled' if active_user.is_default_avatar() else '' }}>
|
||||
</div>
|
||||
<span>1MB maximum size. Avatar will be scaled down to fit a square.</span>
|
||||
</form>
|
||||
</fieldset>
|
||||
<fieldset class="hfc">
|
||||
<legend>Personalization</legend>
|
||||
<form method='post'>
|
||||
<label for='theme'>Theme (beta)</label>
|
||||
<select autocomplete='off' id='theme' name='theme'>
|
||||
{% for theme in config.allowed_themes %}
|
||||
<option value="{{ theme }}" {{ 'selected' if get_prefers_theme() == theme }}>{{ theme | theme_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for='topic_sort_by'>Sort threads by:</label>
|
||||
<select id='topic_sort_by' name='topic_sort_by'>
|
||||
<option value='activity' {{ 'selected' if session['sort_by'] == 'activity' else '' }}>Latest activity</option>
|
||||
<option value='thread' {{ 'selected' if session['sort_by'] == 'thread' else '' }}>Thread creation date</option>
|
||||
</select>
|
||||
<label for='display_name'>Display name</label>
|
||||
<input type='text' id='display_name' name='display_name' value='{{ active_user.display_name }}' pattern="(?:[\w!#$%^*\(\)\-_=+\[\]\{\}\|;:,.?\s]{3,50})?" title='3-50 characters, no @, no <>, no &' placeholder='Optional. Will be shown in place of username.' autocomplete='off'></input>
|
||||
<label for='status'>Status</label>
|
||||
<input type='text' id='status' name='status' value='{{ active_user.status }}' maxlength=100 placeholder='Will be shown under your name. Max 100 characters.'>
|
||||
<input autocomplete='off' type='checkbox' id='subscribe_by_default' name='subscribe_by_default' {{ 'checked' if session.get('subscribe_by_default', default=true) else '' }}>
|
||||
<label for='subscribe_by_default'>Subscribe to thread by default when responding</label><br>
|
||||
<label for='babycode-content'>Signature</label>
|
||||
{{ babycode_editor_component(ta_name='signature', prefill=active_user.signature_original_markup, ta_placeholder='Will be shown under each of your posts', optional=true, banned_tags=SIG_BANNED_TAGS) }}
|
||||
<input type='submit' value='Save settings'>
|
||||
</form>
|
||||
</fieldset>
|
||||
<fieldset class="hfc">
|
||||
<legend>Change password</legend>
|
||||
<form method='post' action='{{ url_for('users.change_password', username=active_user.username) }}'>
|
||||
<label for="new_password">New password</label><br>
|
||||
<input type="password" id="new_password" name="new_password" pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_])(?!.*\s).{10,}" title="10+ chars with: 1 uppercase, 1 lowercase, 1 number, 1 special char, and no spaces" required autocomplete="new-password"><br>
|
||||
<label for="new_password2">Confirm new password</label><br>
|
||||
<input type="password" id="new_password2" name="new_password2" pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_])(?!.*\s).{10,}" title="10+ chars with: 1 uppercase, 1 lowercase, 1 number, 1 special char, and no spaces" required autocomplete="new-password"><br>
|
||||
<input class="warn" type="submit" value="Change password">
|
||||
</form>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div>
|
||||
<a class="linkbutton critical" href="{{ url_for('users.delete_page', username=active_user.username) }}">Delete account</a>
|
||||
</div>
|
||||
|
||||
@@ -6,3 +6,8 @@ DISABLE_SIGNUP = false # if true, no one can sign up.
|
||||
|
||||
MODS_CAN_INVITE = true # if true, allows moderators to create invite links. useless unless DISABLE_SIGNUP to be true.
|
||||
USERS_CAN_INVITE = false # if true, allows users to create invite links. useless unless DISABLE_SIGNUP to be true.
|
||||
|
||||
# contact information, will be shown in /guides/contact
|
||||
# some babycodes allowed
|
||||
# forbidden tags: [spoiler], [img], @mention, [big], [small], [center], [right], [color]
|
||||
ADMIN_CONTACT_INFO = ""
|
||||
|
||||
@@ -26,10 +26,26 @@
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-Italic-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: italic;
|
||||
}
|
||||
*, ::before, ::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.reaction-button.active, .tab-button, .currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton {
|
||||
cursor: default;
|
||||
font-size: 0.9em;
|
||||
font-family: "Cadman";
|
||||
font-size: 1rem;
|
||||
font-family: "Cadman", sans-serif;
|
||||
text-decoration: none;
|
||||
border: 1px solid black;
|
||||
border-radius: 4px;
|
||||
@@ -38,7 +54,7 @@
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
margin: 20px 100px;
|
||||
background-color: rgb(173.5214173228, 183.6737007874, 161.0262992126);
|
||||
color: black;
|
||||
@@ -73,6 +89,16 @@ a:visited {
|
||||
background-color: rgb(143.7039271654, 144.3879625984, 142.8620374016);
|
||||
}
|
||||
|
||||
#footer {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
background-color: rgb(143.7039271654, 144.3879625984, 142.8620374016);
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.darkbg {
|
||||
padding-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
@@ -188,6 +214,10 @@ a:visited {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
background-color: rgb(38.5714173228, 40.9237007874, 35.6762992126);
|
||||
@@ -550,7 +580,7 @@ pre code { /* Literal.Number.Integer.Long */ }
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
border-top-right-radius: 8px;
|
||||
border-top-left-radius: 8px;
|
||||
background-color: #c1ceb1;
|
||||
@@ -814,15 +844,13 @@ p {
|
||||
}
|
||||
|
||||
.login-container > * {
|
||||
width: 70%;
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.settings-container > * {
|
||||
width: 70%;
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.avatar-form {
|
||||
@@ -837,15 +865,20 @@ input[type=text], input[type=password], textarea, select {
|
||||
border-radius: 4px;
|
||||
padding: 7px 10px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
color: black;
|
||||
background-color: rgb(217.8, 225.6, 208.2);
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
}
|
||||
input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus {
|
||||
background-color: rgb(230.2, 235.4, 223.8);
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
.infobox {
|
||||
border: 2px solid black;
|
||||
background-color: #81a3e6;
|
||||
@@ -951,14 +984,14 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
margin-right: 25%;
|
||||
}
|
||||
|
||||
.babycode-guide-section {
|
||||
.guide-section {
|
||||
background-color: #c1ceb1;
|
||||
padding: 5px 20px;
|
||||
border: 1px solid black;
|
||||
padding-right: 25%;
|
||||
}
|
||||
|
||||
.babycode-guide-container {
|
||||
.guide-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr 300px;
|
||||
grid-template-rows: 1fr;
|
||||
@@ -1096,7 +1129,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
|
||||
.babycode-editor {
|
||||
height: 150px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.babycode-editor-container {
|
||||
@@ -1189,7 +1221,6 @@ ul.horizontal li, ol.horizontal li {
|
||||
.accordion {
|
||||
border-top-right-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid black;
|
||||
margin: 10px 5px;
|
||||
overflow: hidden;
|
||||
@@ -1432,3 +1463,18 @@ a.mention:hover, a.mention:visited:hover {
|
||||
background-color: rgb(229.84, 231.92, 227.28);
|
||||
color: black;
|
||||
}
|
||||
|
||||
.settings-grid {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
--grid-item-max-width: calc((100% - 10px) / 2);
|
||||
grid-template-columns: repeat(auto-fill, minmax(max(400px, var(--grid-item-max-width)), 1fr));
|
||||
}
|
||||
.settings-grid fieldset {
|
||||
border: 1px solid white;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.hfc {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
@@ -26,10 +26,26 @@
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-Italic-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: italic;
|
||||
}
|
||||
*, ::before, ::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.reaction-button.active, .tab-button, .currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton {
|
||||
cursor: default;
|
||||
font-size: 0.9em;
|
||||
font-family: "Cadman";
|
||||
font-size: 1rem;
|
||||
font-family: "Cadman", sans-serif;
|
||||
text-decoration: none;
|
||||
border: 1px solid black;
|
||||
border-radius: 8px;
|
||||
@@ -38,7 +54,7 @@
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
margin: 20px 100px;
|
||||
background-color: #220d16;
|
||||
color: #e6e6e6;
|
||||
@@ -73,6 +89,16 @@ a:visited {
|
||||
background-color: #231c23;
|
||||
}
|
||||
|
||||
#footer {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
background-color: #231c23;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.darkbg {
|
||||
padding-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
@@ -188,6 +214,10 @@ a:visited {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
background-color: #302731;
|
||||
@@ -550,7 +580,7 @@ pre code { /* Literal.Number.Integer.Long */ }
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
border-top-right-radius: 8px;
|
||||
border-top-left-radius: 8px;
|
||||
background-color: #9b649b;
|
||||
@@ -814,15 +844,13 @@ p {
|
||||
}
|
||||
|
||||
.login-container > * {
|
||||
width: 70%;
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.settings-container > * {
|
||||
width: 70%;
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.avatar-form {
|
||||
@@ -837,15 +865,20 @@ input[type=text], input[type=password], textarea, select {
|
||||
border-radius: 8px;
|
||||
padding: 7px 10px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
color: #e6e6e6;
|
||||
background-color: #371e37;
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
}
|
||||
input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus {
|
||||
background-color: #514151;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
.infobox {
|
||||
border: 2px solid black;
|
||||
background-color: #775891;
|
||||
@@ -951,14 +984,14 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
margin-right: 25%;
|
||||
}
|
||||
|
||||
.babycode-guide-section {
|
||||
.guide-section {
|
||||
background-color: #231c23;
|
||||
padding: 5px 20px;
|
||||
border: 1px solid black;
|
||||
padding-right: 25%;
|
||||
}
|
||||
|
||||
.babycode-guide-container {
|
||||
.guide-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr 300px;
|
||||
grid-template-rows: 1fr;
|
||||
@@ -1096,7 +1129,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
|
||||
.babycode-editor {
|
||||
height: 150px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.babycode-editor-container {
|
||||
@@ -1189,7 +1221,6 @@ ul.horizontal li, ol.horizontal li {
|
||||
.accordion {
|
||||
border-top-right-radius: 8px;
|
||||
border-top-left-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid black;
|
||||
margin: 10px 5px;
|
||||
overflow: hidden;
|
||||
@@ -1433,6 +1464,21 @@ a.mention:hover, a.mention:visited:hover {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.settings-grid {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
--grid-item-max-width: calc((100% - 10px) / 2);
|
||||
grid-template-columns: repeat(auto-fill, minmax(max(400px, var(--grid-item-max-width)), 1fr));
|
||||
}
|
||||
.settings-grid fieldset {
|
||||
border: 1px solid black;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.hfc {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
#topnav {
|
||||
margin-bottom: 10px;
|
||||
border: 10px solid rgb(40, 40, 40);
|
||||
|
||||
@@ -26,10 +26,26 @@
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-Italic-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: italic;
|
||||
}
|
||||
*, ::before, ::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.reaction-button.active, .tab-button, .currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton {
|
||||
cursor: default;
|
||||
font-size: 0.9em;
|
||||
font-family: "Cadman";
|
||||
font-size: 1rem;
|
||||
font-family: "Cadman", sans-serif;
|
||||
text-decoration: none;
|
||||
border: 1px solid black;
|
||||
border-radius: 16px;
|
||||
@@ -38,7 +54,7 @@
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
margin: 12px 50px;
|
||||
background-color: #c85d45;
|
||||
color: black;
|
||||
@@ -73,6 +89,16 @@ a:visited {
|
||||
background-color: #88486d;
|
||||
}
|
||||
|
||||
#footer {
|
||||
padding: 6px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
background-color: #88486d;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.darkbg {
|
||||
padding-bottom: 6px;
|
||||
padding-left: 6px;
|
||||
@@ -188,6 +214,10 @@ a:visited {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
background-color: rgb(41.7051685393, 28.2759550562, 24.6948314607);
|
||||
@@ -550,7 +580,7 @@ pre code { /* Literal.Number.Integer.Long */ }
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
border-top-right-radius: 16px;
|
||||
border-top-left-radius: 16px;
|
||||
background-color: #f27a5a;
|
||||
@@ -814,15 +844,13 @@ p {
|
||||
}
|
||||
|
||||
.login-container > * {
|
||||
width: 70%;
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.settings-container > * {
|
||||
width: 70%;
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.avatar-form {
|
||||
@@ -837,15 +865,20 @@ input[type=text], input[type=password], textarea, select {
|
||||
border-radius: 16px;
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
color: black;
|
||||
background-color: rgb(247.2, 175.2, 156);
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
}
|
||||
input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus {
|
||||
background-color: rgb(249.8, 201.8, 189);
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
.infobox {
|
||||
border: 2px solid black;
|
||||
background-color: #81a3e6;
|
||||
@@ -951,14 +984,14 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
margin-right: 25%;
|
||||
}
|
||||
|
||||
.babycode-guide-section {
|
||||
.guide-section {
|
||||
background-color: #f27a5a;
|
||||
padding: 3px 12px;
|
||||
border: 1px solid black;
|
||||
padding-right: 25%;
|
||||
}
|
||||
|
||||
.babycode-guide-container {
|
||||
.guide-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr 300px;
|
||||
grid-template-rows: 1fr;
|
||||
@@ -1096,7 +1129,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
|
||||
.babycode-editor {
|
||||
height: 150px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.babycode-editor-container {
|
||||
@@ -1189,7 +1221,6 @@ ul.horizontal li, ol.horizontal li {
|
||||
.accordion {
|
||||
border-top-right-radius: 16px;
|
||||
border-top-left-radius: 16px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid black;
|
||||
margin: 6px 3px;
|
||||
overflow: hidden;
|
||||
@@ -1433,6 +1464,21 @@ a.mention:hover, a.mention:visited:hover {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.settings-grid {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
--grid-item-max-width: calc((100% - 6px) / 2);
|
||||
grid-template-columns: repeat(auto-fill, minmax(max(400px, var(--grid-item-max-width)), 1fr));
|
||||
}
|
||||
.settings-grid fieldset {
|
||||
border: 1px solid white;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.hfc {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
#topnav {
|
||||
border-top-left-radius: 16px;
|
||||
border-top-right-radius: 16px;
|
||||
|
||||
Binary file not shown.
BIN
data/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf
Normal file
BIN
data/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf
Normal file
Binary file not shown.
@@ -51,8 +51,7 @@ $BIGGER_PADDING: 30px !default;
|
||||
|
||||
$PAGE_SIDE_MARGIN: 100px !default;
|
||||
|
||||
$SETTINGS_WIDTH: 70% !default;
|
||||
$SETTINGS_MAX_WIDTH: 1000px !default;
|
||||
$SETTINGS_WIDTH: 85% !default;
|
||||
|
||||
// **************
|
||||
// BORDERS
|
||||
@@ -96,14 +95,32 @@ $DEFAULT_BORDER_RADIUS: 4px !default;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Atkinson Hyperlegible Mono";
|
||||
src: url("/static/fonts/AtkinsonHyperlegibleMono-Italic-VariableFont_wght.ttf");
|
||||
font-weight: 125 950;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
*, ::before, ::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
$button_border: $DEFAULT_BORDER !default;
|
||||
$button_padding: $SMALL_PADDING $BIG_PADDING !default;
|
||||
$button_border_radius: $DEFAULT_BORDER_RADIUS !default;
|
||||
$button_margin: $MEDIUM_PADDING $ZERO_PADDING !default;
|
||||
%button-base {
|
||||
cursor: default;
|
||||
font-size: 0.9em;
|
||||
font-family: "Cadman";
|
||||
font-size: 1rem;
|
||||
font-family: "Cadman", sans-serif;
|
||||
text-decoration: none;
|
||||
border: $button_border;
|
||||
border-radius: $button_border_radius;
|
||||
@@ -155,7 +172,7 @@ $navbar_margin: 0 !default;
|
||||
|
||||
$body_margin: $BIG_PADDING $PAGE_SIDE_MARGIN !default;
|
||||
body {
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
// font-size: 18px;
|
||||
margin: $body_margin;
|
||||
background-color: $MAIN_BG;
|
||||
@@ -189,6 +206,12 @@ $bottomnav_color: $DARK_1 !default;
|
||||
@include navbar($bottomnav_color);
|
||||
}
|
||||
|
||||
#footer {
|
||||
@include navbar($bottomnav_color);
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
$darkbg_color: $DARK_1 !default;
|
||||
.darkbg {
|
||||
padding-bottom: $MEDIUM_PADDING;
|
||||
@@ -341,6 +364,10 @@ $signature_container_padding: $MEDIUM_PADDING $ZERO_PADDING !default;
|
||||
padding: $signature_container_padding;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
$code_background_color: $DARK_3 !default;
|
||||
$code_font_color: white !default;
|
||||
$code_border_radius: 8px !default;
|
||||
@@ -445,7 +472,7 @@ $copy_code_border: 2px solid black !default;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
font-family: "Cadman";
|
||||
font-family: "Cadman", sans-serif;
|
||||
border-top-right-radius: $code_border_radius;
|
||||
border-top-left-radius: $code_border_radius;
|
||||
background-color: $copy_code_header_background;
|
||||
@@ -655,19 +682,15 @@ $pagebutton_min_width: $BIG_PADDING !default;
|
||||
}
|
||||
|
||||
$login_container_width: $SETTINGS_WIDTH !default;
|
||||
$login_container_max_width: $SETTINGS_MAX_WIDTH !default;
|
||||
.login-container > * {
|
||||
width: $login_container_width;
|
||||
margin: auto;
|
||||
max-width: $login_container_max_width;
|
||||
}
|
||||
|
||||
$settings_container_width: $SETTINGS_WIDTH !default;
|
||||
$settings_container_max_width: $SETTINGS_MAX_WIDTH !default;
|
||||
.settings-container > * {
|
||||
width: $settings_container_width;
|
||||
margin: auto;
|
||||
max-width: $settings_container_max_width
|
||||
}
|
||||
|
||||
$avatar_form_padding: $BIG_PADDING $ZERO_PADDING !default;
|
||||
@@ -689,16 +712,21 @@ input[type="text"], input[type="password"], textarea, select {
|
||||
border-radius: $text_input_border_radius;
|
||||
padding: $text_input_padding;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
color: $text_input_font_color;
|
||||
background-color: $text_input_background;
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
|
||||
&:focus {
|
||||
background-color: $text_input_background_focus;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-family: "Atkinson Hyperlegible Mono", monospace;
|
||||
}
|
||||
|
||||
$infobox_info_color: #81a3e6 !default;
|
||||
$infobox_critical_color: #ed8181 !default;
|
||||
$infobox_warn_color: #fbfb8d !default;
|
||||
@@ -833,24 +861,24 @@ $thread_info_post_preview_margin_right: $post_inner_padding_right !default;
|
||||
margin-right: $thread_info_post_preview_margin_right;
|
||||
}
|
||||
|
||||
$babycode_guide_section_background: $ACCENT_COLOR !default;
|
||||
$babycode_guide_section_padding: $SMALL_PADDING $BIG_PADDING !default;
|
||||
$babycode_guide_section_border: $DEFAULT_BORDER !default;
|
||||
$babycode_guide_section_padding_right: $post_inner_padding_right !default;
|
||||
.babycode-guide-section {
|
||||
background-color: $babycode_guide_section_background;
|
||||
padding: $babycode_guide_section_padding;
|
||||
border: $babycode_guide_section_border;
|
||||
padding-right: $babycode_guide_section_padding_right;
|
||||
$guide_section_background: $ACCENT_COLOR !default;
|
||||
$guide_section_padding: $SMALL_PADDING $BIG_PADDING !default;
|
||||
$guide_section_border: $DEFAULT_BORDER !default;
|
||||
$guide_section_padding_right: $post_inner_padding_right !default;
|
||||
.guide-section {
|
||||
background-color: $guide_section_background;
|
||||
padding: $guide_section_padding;
|
||||
border: $guide_section_border;
|
||||
padding-right: $guide_section_padding_right;
|
||||
}
|
||||
|
||||
$babycode_guide_toc_width: 300px !default;
|
||||
$babycode_guide_column_guide: $ZERO_PADDING !default;
|
||||
.babycode-guide-container {
|
||||
$guide_toc_width: 300px !default;
|
||||
$guide_column_guide: $ZERO_PADDING !default;
|
||||
.guide-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr $babycode_guide_toc_width;
|
||||
grid-template-columns: 1.5fr $guide_toc_width;
|
||||
grid-template-rows: 1fr;
|
||||
gap: $babycode_guide_column_guide;
|
||||
gap: $guide_column_guide;
|
||||
grid-auto-flow: row;
|
||||
grid-template-areas:
|
||||
"guide-topics guide-toc";
|
||||
@@ -861,21 +889,21 @@ $babycode_guide_column_guide: $ZERO_PADDING !default;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
$babycode_guide_toc_padding: $MEDIUM_PADDING !default;
|
||||
$babycode_guide_toc_background: $BUTTON_COLOR !default;
|
||||
$babycode_guide_toc_border_radius: 8px !default;
|
||||
$babycode_guide_toc_border: $DEFAULT_BORDER !default;
|
||||
$guide_toc_padding: $MEDIUM_PADDING !default;
|
||||
$guide_toc_background: $BUTTON_COLOR !default;
|
||||
$guide_toc_border_radius: 8px !default;
|
||||
$guide_toc_border: $DEFAULT_BORDER !default;
|
||||
.guide-toc {
|
||||
grid-area: guide-toc;
|
||||
position: sticky;
|
||||
top: 100px;
|
||||
align-self: start;
|
||||
padding: $babycode_guide_toc_padding;
|
||||
border-bottom-right-radius: $babycode_guide_toc_border_radius;
|
||||
background-color: $babycode_guide_toc_background;
|
||||
border-right: $babycode_guide_toc_border;
|
||||
border-top: $babycode_guide_toc_border;
|
||||
border-bottom: $babycode_guide_toc_border;
|
||||
padding: $guide_toc_padding;
|
||||
border-bottom-right-radius: $guide_toc_border_radius;
|
||||
background-color: $guide_toc_background;
|
||||
border-right: $guide_toc_border;
|
||||
border-top: $guide_toc_border;
|
||||
border-bottom: $guide_toc_border;
|
||||
}
|
||||
|
||||
.emoji-table tr td {
|
||||
@@ -1025,7 +1053,6 @@ $post_editing_context_margin: $BIG_PADDING $ZERO_PADDING !default;
|
||||
|
||||
.babycode-editor {
|
||||
height: 150px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.babycode-editor-container {
|
||||
@@ -1118,7 +1145,6 @@ $accordion_margin: $MEDIUM_PADDING $SMALL_PADDING !default;
|
||||
.accordion {
|
||||
border-top-right-radius: $accordion_border_radius;
|
||||
border-top-left-radius: $accordion_border_radius;
|
||||
box-sizing: border-box;
|
||||
border: $accordion_border;
|
||||
margin: $accordion_margin;
|
||||
overflow: hidden; // for border-radius clipping
|
||||
@@ -1405,5 +1431,25 @@ a.mention, a.mention:visited {
|
||||
background-color: $mention_background_color_hover;
|
||||
color: $mention_font_color_hover;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$settings_grid_gap: $MEDIUM_PADDING !default;
|
||||
$settings_grid_item_min_width: 400px !default;
|
||||
$settings_grid_fieldset_border: 1px solid $DEFAULT_FONT_COLOR_INVERSE !default;
|
||||
$settings_grid_fieldset_border_radius: $DEFAULT_BORDER_RADIUS !default;
|
||||
.settings-grid {
|
||||
display: grid;
|
||||
gap: $settings_grid_gap;
|
||||
|
||||
--grid-item-max-width: calc((100% - #{$settings_grid_gap}) / 2);
|
||||
grid-template-columns: repeat(auto-fill, minmax(max($settings_grid_item_min_width, var(--grid-item-max-width)), 1fr));
|
||||
|
||||
& fieldset {
|
||||
border: $settings_grid_fieldset_border;
|
||||
border-radius: $settings_grid_fieldset_border_radius;
|
||||
}
|
||||
}
|
||||
|
||||
.hfc {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ $br: 8px;
|
||||
|
||||
$post_accordion_content_background: #2d212d,
|
||||
|
||||
$babycode_guide_toc_background: #3c233c,
|
||||
$babycode_guide_section_background: $dark_accent,
|
||||
$guide_toc_background: #3c233c,
|
||||
$guide_section_background: $dark_accent,
|
||||
|
||||
$text_input_background: #371e37,
|
||||
$text_input_background_focus: #514151,
|
||||
|
||||
Reference in New Issue
Block a user