new settings page

This commit is contained in:
2025-12-04 02:28:34 +03:00
parent 3742749cf6
commit 3baccb87b1
5 changed files with 122 additions and 57 deletions

View File

@@ -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) }}
<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>

View File

@@ -814,15 +814,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 {
@@ -1432,3 +1430,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;
}

View File

@@ -814,15 +814,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 {
@@ -1433,6 +1431,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);

View File

@@ -814,15 +814,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 {
@@ -1433,6 +1431,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;

View File

@@ -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
@@ -655,19 +654,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;
@@ -1405,5 +1400,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;
}