Update settings page

This commit is contained in:
Patrick Jentsch 2023-03-27 13:56:24 +02:00
parent 020de69e45
commit df870c1c7d
5 changed files with 112 additions and 116 deletions

View File

@ -1,7 +1,6 @@
from flask_login import current_user
from flask_wtf import FlaskForm
from wtforms import (
BooleanField,
FileField,
PasswordField,
SelectField,
@ -67,9 +66,6 @@ class EditAccountForm(FlaskForm):
class EditProfileForm(FlaskForm):
show_email = BooleanField('Email')
show_last_seen = BooleanField('Last seen')
show_member_since = BooleanField('Member since')
avatar = FileField(
'Image File',
[FileSizeLimit(max_size_in_mb=2)]

View File

@ -7,6 +7,7 @@ from app.decorators import content_negotiation
from app.models import Avatar, User, ProfilePrivacySettings
from . import bp
@bp.route('/<hashid:user_id>', methods=['DELETE'])
@login_required
@content_negotiation(produces='application/json')
@ -32,6 +33,7 @@ def delete_user(user_id):
}
return response_data, 202
@bp.route('/<hashid:user_id>/avatar', methods=['DELETE'])
@content_negotiation(produces='application/json')
def delete_profile_avatar(user_id):
@ -53,7 +55,8 @@ def delete_profile_avatar(user_id):
}
return response_data, 202
@bp.route('/<hashid:user_id>/is_public', methods=['PUT'])
@bp.route('/<hashid:user_id>/is-public', methods=['PUT'])
@login_required
@content_negotiation(consumes='application/json', produces='application/json')
def update_user_is_public(user_id):
@ -73,26 +76,25 @@ def update_user_is_public(user_id):
return response_data, 200
# @bp.route('/<hashid:user_id>/profile-privacy-settings', methods=['PUT'])
# @login_required
# @content_negotiation(consumes='application/json', produces='application/json')
# def update_profile_privacy_settings(user_id):
# profile_privacy_settings = request.json
# if not isinstance(profile_privacy_settings, list):
# abort(400)
# for profile_privacy_setting in profile_privacy_settings:
# if not isinstance(profile_privacy_setting, str):
# abort(400)
# if not profile_privacy_setting in ProfilePrivacySettings.__members__:
# abort(400)
# user = User.query.get_or_404(user_id)
# user.is_public = is_public
# db.session.commit()
# response_data = {
# 'message': (
# f'User "{user.username}" is now'
# f' {"public" if is_public else "private"}'
# ),
# 'category': 'corpus'
# }
# return response_data, 200
@bp.route('/<hashid:user_id>/profile-privacy-settings/<string:profile_privacy_setting_name>', methods=['PUT'])
@login_required
@content_negotiation(consumes='application/json', produces='application/json')
def add_profile_privacy_settings(user_id, profile_privacy_setting_name):
user = User.query.get_or_404(user_id)
enabled = request.json
if not isinstance(enabled, bool):
abort(400)
try:
profile_privacy_setting = ProfilePrivacySettings[profile_privacy_setting_name]
except KeyError:
abort(404)
if enabled:
user.add_profile_privacy_setting(profile_privacy_setting)
else:
user.remove_profile_privacy_setting(profile_privacy_setting)
db.session.commit()
response_data = {
'message': 'Profile privacy settings updated',
'category': 'corpus'
}
return response_data, 200

View File

@ -33,18 +33,6 @@ def settings():
# endregion handle edit profile settings forms
# region handle edit public profile information form
if edit_profile_form.validate_on_submit():
if edit_profile_form.show_email.data:
user.add_profile_privacy_setting('SHOW_EMAIL')
else:
user.remove_profile_privacy_setting('SHOW_EMAIL')
if edit_profile_form.show_last_seen.data:
user.add_profile_privacy_setting('SHOW_LAST_SEEN')
else:
user.remove_profile_privacy_setting('SHOW_LAST_SEEN')
if edit_profile_form.show_member_since.data:
user.add_profile_privacy_setting('SHOW_MEMBER_SINCE')
else:
user.remove_profile_privacy_setting('SHOW_MEMBER_SINCE')
if edit_profile_form.avatar.data:
try:
Avatar.create(

View File

@ -25,7 +25,7 @@ Requests.settings.entity.deleteAvatar = (userId) => {
Requests.settings.entity.isPublic = {};
Requests.settings.entity.isPublic.update = (userId, isPublic) => {
let input = `/settings/${userId}/is_public`;
let input = `/settings/${userId}/is-public`;
let init = {
method: 'PUT',
body: JSON.stringify(isPublic)
@ -33,3 +33,13 @@ Requests.settings.entity.isPublic.update = (userId, isPublic) => {
return Requests.JSONfetch(input, init);
};
Requests.settings.entity.profilePrivacySettings = {};
Requests.settings.entity.profilePrivacySettings.update = (userId, profilePrivacySetting, enabled) => {
let input = `/settings/${userId}/profile-privacy-settings/${profilePrivacySetting}`;
let init = {
method: 'PUT',
body: JSON.stringify(enabled)
};
return Requests.JSONfetch(input, init);
}

View File

@ -9,81 +9,62 @@
</div>
</div>
<div class="row">
<div class="col s4">
<div class="col s12 l4">
<h4>Profile Settings</h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea tak</p>
</div>
<div class="col s8">
<div class="col s12 l8">
<br>
<ul class="collapsible no-autoinit settings-collapsible">
<li>
<div class="collapsible-header" style="justify-content: space-between;"><span>Public Profile</span><i class="material-icons caret right">keyboard_arrow_right</i></div>
<div class="collapsible-header" style="justify-content: space-between;">
<span>Profile Privacy Settings</span>
<i class="material-icons caret">keyboard_arrow_right</i>
</div>
<div class="collapsible-body">
<div class="row">
<div class="col s12 l3">
<div class="switch">
<label>
private
<input {% if user.is_public %}checked{% endif %} id="profile-is-public-switch" type="checkbox">
<span class="lever"></span>
public
</label>
</div>
</div>
<div class="col s12 l3">
<label>
<input {% if user.has_profile_privacy_setting('SHOW_EMAIL') %}checked{% endif %} class="profile-privacy-setting-checkbox" data-profile-privacy-setting-name="SHOW_EMAIL" {% if not user.is_public %}disabled{% endif %} type="checkbox">
<span>Email</span>
</label>
</div>
<div class="col s12 l3">
<label>
<input {% if user.has_profile_privacy_setting('SHOW_LAST_SEEN') %}checked{% endif %} class="profile-privacy-setting-checkbox" data-profile-privacy-setting-name="SHOW_LAST_SEEN" {% if not user.is_public %}disabled{% endif %} type="checkbox">
<span>Last seen</span>
</label>
</div>
<div class="col s12 l3">
<label>
<input {% if user.has_profile_privacy_setting('SHOW_MEMBER_SINCE') %}checked{% endif %} class="profile-privacy-setting-checkbox" data-profile-privacy-setting-name="SHOW_MEMBER_SINCE" {% if not user.is_public %}disabled{% endif %} type="checkbox">
<span>Member since</span>
</label>
</div>
</div>
</div>
</li>
<li>
<div class="collapsible-header" style="justify-content: space-between;">
<span>Profile information</span>
<i class="material-icons caret">keyboard_arrow_right</i>
</div>
<div class="collapsible-body">
<form method="POST" enctype="multipart/form-data">
{{ edit_profile_form.hidden_tag() }}
<div class="switch">
<label>
private
<input {% if user.is_public %}checked{% endif %} id="profile-is-public-switch" type="checkbox">
<span class="lever"></span>
public
</label>
</div>
<p></p>
<br>
<div class="divider"></div>
<p>Show:</p>
<div class="row">
<div class="col s3">
<label>
<input {% if user.has_profile_privacy_setting('SHOW_EMAIL') %}checked{% endif %} id="profile-show-email-checkbox" type="checkbox">
<span>Email</span>
</label>
</div>
<div class="col s3">
<label>
<input {% if user.has_profile_privacy_setting('SHOW_LAST_SEEN') %}checked{% endif %} id="profile-show-last-seen-checkbox" type="checkbox">
<span>Last seen</span>
</label>
</div>
<div class="col s3">
<label>
<input {% if user.has_profile_privacy_setting('SHOW_MEMBER_SINCE') %}checked{% endif %} id="profile-show-member-since-checkbox" type="checkbox">
<span>Member since</span>
</label>
</div>
</div>
{# <div class="row">
<div class="col s3">
<p>
<label>
{{ edit_profile_form.show_email() }}
<span>{{ edit_profile_form.show_email.label.text }}</span>
</label>
</p>
</div>
<div class="col s3">
<p>
<label>
{{ edit_profile_form.show_last_seen() }}
<span>{{ edit_profile_form.show_last_seen.label.text }}</span>
</label>
</p>
</div>
<div class="col s4">
<p>
<label>
{{ edit_profile_form.show_member_since() }}
<span>{{ edit_profile_form.show_member_since.label.text }}</span>
</label>
</p>
</div>
</div> #}
<p></p>
<br>
{{ wtf.render_field(edit_profile_form.full_name, material_icon='badge') }}
{{ wtf.render_field(edit_profile_form.about_me, material_icon='description', id='about-me-textfield') }}
{{ wtf.render_field(edit_profile_form.website, material_icon='laptop') }}
@ -113,20 +94,20 @@
</div>
</div>
<div class="row">
<div class="col s4">
<div class="col s12 l4">
<h4>General Settings</h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea tak</p>
</div>
<div class="col s8">
<div class="col s12 l8">
<br>
<ul class="collapsible no-autoinit settings-collapsible">
<li>
<div class="collapsible-header" style="justify-content: space-between;">
<span>Account</span>
<i class="caret material-icons right">keyboard_arrow_right</i>
<i class="caret material-icons">keyboard_arrow_right</i>
</div>
<div class="collapsible-body">
<form method="POST" enctype="multipart/form-data">
@ -167,7 +148,7 @@
<li>
<div class="collapsible-header" style="justify-content: space-between;">
<span>Change Password</span>
<i class="caret material-icons right">keyboard_arrow_right</i>
<i class="caret material-icons">keyboard_arrow_right</i>
</div>
<div class="collapsible-body">
<form method="POST">
@ -199,6 +180,7 @@
<a class="btn modal-close red waves-effect waves-light" id="delete-avatar">Delete</a>
</div>
</div>
<div class="modal" id="delete-user">
<div class="modal-content">
<h4>Confirm User deletion</h4>
@ -224,7 +206,7 @@ avatarUploadElement.addEventListener('change', () => {
});
deleteButtonElement.addEventListener('click', () => {
Requests.settings.entity.deleteAvatar(currentUserId)
Requests.settings.entity.deleteAvatar({{ user.hashid|tojson }})
.then(
(response) => {
avatarElement.src = {{ url_for('static', filename='images/user_avatar.png')|tojson }};
@ -233,7 +215,7 @@ deleteButtonElement.addEventListener('click', () => {
});
document.querySelector('#delete-user-button').addEventListener('click', (event) => {
Requests.settings.entity.delete(currentUserId)
Requests.settings.entity.delete({{ user.hashid|tojson }})
.then((response) => {window.location.href = '/';});
});
@ -253,15 +235,33 @@ for (let collapsibleElement of document.querySelectorAll('.collapsible.no-autoin
);
}
// #region Public Switch
// #region Profile Privacy settings
let profileIsPublicSwitchElement = document.querySelector('#profile-is-public-switch');
let profilePrivacySettingCheckboxElements = document.querySelectorAll('.profile-privacy-setting-checkbox');
profileIsPublicSwitchElement.addEventListener('change', (event) => {
let newIsPublic = profileIsPublicSwitchElement.checked;
Requests.settings.entity.isPublic.update(currentUserId, newIsPublic)
.catch((response) => {
profileIsPublicSwitchElement.checked = !newIsPublic;
});
Requests.settings.entity.isPublic.update({{ user.hashid|tojson }}, newIsPublic)
.then(
(response) => {
for (let profilePrivacySettingCheckboxElement of document.querySelectorAll('.profile-privacy-setting-checkbox')) {
profilePrivacySettingCheckboxElement.disabled = !newIsPublic;
}
},
(response) => {
profileIsPublicSwitchElement.checked = !newIsPublic;
}
);
});
// #endregion Public Switch
for (let profilePrivacySettingCheckboxElement of profilePrivacySettingCheckboxElements) {
profilePrivacySettingCheckboxElement.addEventListener('change', (event) => {
let newEnabled = profilePrivacySettingCheckboxElement.checked;
let valueName = profilePrivacySettingCheckboxElement.dataset.profilePrivacySettingName;
Requests.settings.entity.profilePrivacySettings.update({{ user.hashid|tojson }}, valueName, newEnabled)
.catch((response) => {
profilePrivacySettingCheckboxElement.checked = !newEnabled;
});
});
}
// #endregion Profile Privacy settings
</script>
{% endblock scripts %}