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_login import current_user
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import ( from wtforms import (
BooleanField,
FileField, FileField,
PasswordField, PasswordField,
SelectField, SelectField,
@ -67,9 +66,6 @@ class EditAccountForm(FlaskForm):
class EditProfileForm(FlaskForm): class EditProfileForm(FlaskForm):
show_email = BooleanField('Email')
show_last_seen = BooleanField('Last seen')
show_member_since = BooleanField('Member since')
avatar = FileField( avatar = FileField(
'Image File', 'Image File',
[FileSizeLimit(max_size_in_mb=2)] [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 app.models import Avatar, User, ProfilePrivacySettings
from . import bp from . import bp
@bp.route('/<hashid:user_id>', methods=['DELETE']) @bp.route('/<hashid:user_id>', methods=['DELETE'])
@login_required @login_required
@content_negotiation(produces='application/json') @content_negotiation(produces='application/json')
@ -32,6 +33,7 @@ def delete_user(user_id):
} }
return response_data, 202 return response_data, 202
@bp.route('/<hashid:user_id>/avatar', methods=['DELETE']) @bp.route('/<hashid:user_id>/avatar', methods=['DELETE'])
@content_negotiation(produces='application/json') @content_negotiation(produces='application/json')
def delete_profile_avatar(user_id): def delete_profile_avatar(user_id):
@ -53,7 +55,8 @@ def delete_profile_avatar(user_id):
} }
return response_data, 202 return response_data, 202
@bp.route('/<hashid:user_id>/is_public', methods=['PUT'])
@bp.route('/<hashid:user_id>/is-public', methods=['PUT'])
@login_required @login_required
@content_negotiation(consumes='application/json', produces='application/json') @content_negotiation(consumes='application/json', produces='application/json')
def update_user_is_public(user_id): def update_user_is_public(user_id):
@ -73,26 +76,25 @@ def update_user_is_public(user_id):
return response_data, 200 return response_data, 200
# @bp.route('/<hashid:user_id>/profile-privacy-settings', methods=['PUT']) @bp.route('/<hashid:user_id>/profile-privacy-settings/<string:profile_privacy_setting_name>', methods=['PUT'])
# @login_required @login_required
# @content_negotiation(consumes='application/json', produces='application/json') @content_negotiation(consumes='application/json', produces='application/json')
# def update_profile_privacy_settings(user_id): def add_profile_privacy_settings(user_id, profile_privacy_setting_name):
# profile_privacy_settings = request.json user = User.query.get_or_404(user_id)
# if not isinstance(profile_privacy_settings, list): enabled = request.json
# abort(400) if not isinstance(enabled, bool):
# for profile_privacy_setting in profile_privacy_settings: abort(400)
# if not isinstance(profile_privacy_setting, str): try:
# abort(400) profile_privacy_setting = ProfilePrivacySettings[profile_privacy_setting_name]
# if not profile_privacy_setting in ProfilePrivacySettings.__members__: except KeyError:
# abort(400) abort(404)
# user = User.query.get_or_404(user_id) if enabled:
# user.is_public = is_public user.add_profile_privacy_setting(profile_privacy_setting)
# db.session.commit() else:
# response_data = { user.remove_profile_privacy_setting(profile_privacy_setting)
# 'message': ( db.session.commit()
# f'User "{user.username}" is now' response_data = {
# f' {"public" if is_public else "private"}' 'message': 'Profile privacy settings updated',
# ), 'category': 'corpus'
# 'category': 'corpus' }
# } return response_data, 200
# return response_data, 200

View File

@ -33,18 +33,6 @@ def settings():
# endregion handle edit profile settings forms # endregion handle edit profile settings forms
# region handle edit public profile information form # region handle edit public profile information form
if edit_profile_form.validate_on_submit(): 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: if edit_profile_form.avatar.data:
try: try:
Avatar.create( Avatar.create(

View File

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