diff options
| author | Bobby <[email protected]> | 2023-01-02 14:22:04 -0500 |
|---|---|---|
| committer | Bobby <[email protected]> | 2023-01-02 14:22:04 -0500 |
| commit | 5a40fdd435185290b77596b792d3f6eb81819c16 (patch) | |
| tree | 4f35500b301740d591d5998f1de9d02db718b607 | |
| parent | 24183dbddd0db7c34a020f65e8c52cffadc9b49e (diff) | |
| download | thatcomputerscientist-5a40fdd435185290b77596b792d3f6eb81819c16.tar.xz thatcomputerscientist-5a40fdd435185290b77596b792d3f6eb81819c16.zip | |
post improvements and avatar chooser
| -rw-r--r-- | blog/views.py | 24 | ||||
| -rw-r--r-- | static/css/main.css | 12 | ||||
| -rw-r--r-- | templates/blog/account.html | 70 | ||||
| -rw-r--r-- | templates/blog/partials/base.html | 4 | ||||
| -rw-r--r-- | templates/blog/post.html | 68 | ||||
| -rw-r--r-- | users/urls.py | 1 | ||||
| -rw-r--r-- | users/views.py | 20 |
7 files changed, 158 insertions, 41 deletions
diff --git a/blog/views.py b/blog/views.py index 65e69c3e..90bf7faf 100644 --- a/blog/views.py +++ b/blog/views.py @@ -14,6 +14,18 @@ from django.contrib import messages from bs4 import BeautifulSoup import re +def atoi(text): + return int(text) if text.isdigit() else text + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [ atoi(c) for c in re.split(r'(\d+)', text) ] + + # Create your views here. def home(request): @@ -24,6 +36,12 @@ def home(request): def account(request): user = request.user avatarlist = avatar_list() + for key in avatarlist: + avatarlist[key] = [re.sub(r'\.png$', '', string) for string in avatarlist[key]] + avatarlist[key] = [string.title() for string in avatarlist[key]] + avatarlist[key].sort(key=natural_keys) + + print(avatarlist) if user.is_authenticated: try: user_profile = UserProfile.objects.get(user=user) @@ -31,16 +49,16 @@ def account(request): # Set a random avatar avatar_dir = choice(list(avatarlist.keys())) avatar_file = choice(avatarlist[avatar_dir]) - user_profile.avatar_url = '/static/images/avatars/' + avatar_dir + '/' + avatar_file + user_profile.avatar_url = avatar_dir + '/' + avatar_file user_profile.save() except UserProfile.DoesNotExist: # Create a new user profile and set a random avatar user_profile = UserProfile.objects.create(user=user) avatar_dir = choice(list(avatarlist.keys())) avatar_file = choice(avatarlist[avatar_dir]) - user_profile.avatar_url = '/static/images/avatars/' + avatar_dir + '/' + avatar_file + user_profile.avatar_url = avatar_dir + '/' + avatar_file user_profile.save() - return render(request, 'blog/account.html', {'title': 'Account', 'user_profile': user_profile}) + return render(request, 'blog/account.html', {'title': 'Account', 'user_profile': user_profile, 'avatarlist': avatarlist}) else: # Redirect to login page return redirect('blog:home') diff --git a/static/css/main.css b/static/css/main.css index 20310cb1..fe53f5e0 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -10,6 +10,7 @@ body { margin: 0px auto 0px; padding: 0px; color: #dddddd; + box-sizing: border-box; } #editor-container { @@ -26,7 +27,7 @@ a:hover { text-decoration: underline; } -h2, #editor-container h2 { +h2, h3, #editor-container h2 { color: white; font-size: 11px; font-weight: bold; @@ -37,6 +38,10 @@ h2, #editor-container h2 { margin-bottom: 15px; } +h3 { + text-transform: none; +} + input, textarea, select { padding: 5px 10px; border: none; @@ -159,6 +164,10 @@ kbd { color: #fa3737; } +.success { + color: #00ff00; +} + .ac { margin-right: 5px; height: 12px; @@ -194,6 +203,7 @@ kbd { .highlight { background: none !important; + text-align: left !important; } .comment { diff --git a/templates/blog/account.html b/templates/blog/account.html index 20571b00..6c9ecf8c 100644 --- a/templates/blog/account.html +++ b/templates/blog/account.html @@ -1,8 +1,70 @@ {% extends 'blog/partials/base.html' %} {% block content %} -<h1>My Account</h1> -<div id="avatar-area"> - <img src="{{ user_profile.avatar_url }}" alt="{{ user.username }}'s avatar" width="200" height="200"/> +{% load static %} +<h2 style="margin-top: 0;">My Account</h2> +<div id="profile-area"> + <div style="width: 200px; height: 100%; display: inline; float: left;"> + <div id="avatar-area" style="padding: 10px; margin-bottom: 10px;"> + <img src="{% static 'images/avatars/' %}{{ user_profile.avatar_url }}.png" alt="{{ user.username }}'s avatar" width="140" height="140" style="display: block; margin: 0 auto;" /> + </div> + <div id="side-links"> + <p><a href="{% url 'blog:account' %}">Account Settings</a></p> + <p><a href="{% url 'blog:account' %}?tab=avatar">Change avatar</a></p> + <p><a href="{% url 'blog:account' %}?tab=details">Change details</a></p> + <p><a href="{% url 'blog:account' %}?tab=email">Change email</a></p> + <p><a href="{% url 'blog:account' %}?tab=password">Change password</a></p> + <p><a href="{% url 'blog:account' %}?tab=delete" class="error">Delete account</a></p> + </div> + </div> + <div style="width: 510px; height: 100%; display: inline; float: left; padding: 0px 10px;"> + {% for message in messages %} + <div class="alert {{message.tags}}"> + <p>{{ message }}</p> + </div> + {% endfor %} + {% if request.GET.tab == 'avatar' %} + <div id="avatar-chooser"> + <p>Choose an avatar from the list below. The avatars are grouped by their theme.</p> + <form method="post" action="{% url 'users:updateavatar' %}"> + {% csrf_token %} + {% for avatar_dir, avatar_files in avatarlist.items %} + <h2 style="clear:both;">{{ avatar_dir }}</h2> + <div class="avatar-directory"> + {% for avatar_file in avatar_files %} + <div style="width: 255px; display: inline; float: left;"> + {% with ""|add:avatar_dir|add:"/"|add:avatar_file as avt_url %} + <input type="radio" name="avatar" value="{{ avatar_dir }}/{{ avatar_file }}" id="{{ avatar_dir }}_{{ avatar_file }}" {% if user_profile.avatar_url == avt_url %}checked{% endif %} /> + <label for="{{ avatar_dir }}_{{ avatar_file }}"> + <img src="{% static 'images/avatars/' %}{{ avatar_dir }}/{{ avatar_file }}.png" alt="{{ avatar_file }}" width="50" height="50" loading="lazy" style="vertical-align: middle;" /> + {% load replace %} + <span style="vertical-align: middle; text-transform: captialize">{{ avatar_file|replace:".Png" }}</span> + </label> + {% endwith %} + </div> + {% endfor %} + <div style="clear: both;"></div> + <br><br> + </div> + {% endfor %} + <input type="submit" value="Change Avatar" class="button button-special" /> + </form> + </div> + {% else %} + <div id="help"> + <p>You can change account settings for <strong>{{ user.username }}</strong> here. If you wish to have additional support, please contact me at <a href="mailto:[email protected]?subject=[URGENT]%20Support%20Request%20for%20{{ user.username }}">[email protected]</a>. Please take care of the following points before you submit your support request:</p> + <ul> + <li>Please do not edit the subject line.</li> + <li>As an individual monitoring this email, I request you to refrain yourself from spamming.</li> + <li>Please do not include any sensitive information (like credit card numbers, passwords, etc.) in the email.</li> + <li>Allow me upto 48 hours to respond to your support request.</li> + <li>Do not send multiple support requests.</li> + <li>Please note that this is a support request related to your account. Please do not file any bugs here. If you have noticed a bug, please report it to the <a href="https://github.com/luciferreeves/thatcomputerscientist/issues">GitHub Issues</a> page.</li> + </ul> + </div> + {% endif %} + </div> </div> + +{% comment %} <div id="account-area"> <div id="user-details"> <form method="post" action="{% url 'users:update' %} "> @@ -93,5 +155,5 @@ </form> </div> </div> -</div> +</div> {% endcomment %} {% endblock %} diff --git a/templates/blog/partials/base.html b/templates/blog/partials/base.html index 11da5dd2..34ef317a 100644 --- a/templates/blog/partials/base.html +++ b/templates/blog/partials/base.html @@ -30,10 +30,10 @@ <div id="header"></div> <div id="main-section"> - <div id="sidebar"> + <div id="sidebar" style="display: inline;"> {% include 'blog/partials/sidebar.html' %} </div> - <div id="content"> + <div id="content" style="display: inline;"> {% block content %} {% endblock %} </div> </div> diff --git a/templates/blog/post.html b/templates/blog/post.html index 96032aab..90f7a71a 100644 --- a/templates/blog/post.html +++ b/templates/blog/post.html @@ -67,34 +67,37 @@ <input type="submit" value="Submit" class="button button-special"> </form> <div id="comment-tips" style="color: #d8c6df;"> - <p style="margin-bottom: 0;">Simple markup is supported:</p> - <ul style="list-style-type: disc;margin: 0;padding: 0;margin: 5px 0px 0px 30px;"> - <li>Wrap text in double underscores (__) to make it <i>italic</i>. - <br> -   e.g. <code>__italic__</code> -   shortkey: <kbd>Ctrl or Cmd + I</kbd> - <br><br> - </li> - <li>Wrap text in double asterisks (**) to make it <b>bold</b>. - <br> -   e.g. <code>**bold**</code> -   shortkey: <kbd>Ctrl or Cmd + B</kbd> - <br><br> - </li> - <li>Wrap text in double tildes (~~) to <s>strikethrough</s> it. - <br> -   e.g. <code>~~strikethrough~~</code> -   shortkey: <kbd>Ctrl or Cmd + D</kbd> - <br><br> - </li> - <li>Wrap text in triple backticks (```) to make it a code block. - <br> -   e.g. <code>```code block```</code>, -   shortkey: <kbd>Ctrl or Cmd + K</kbd> - <br><br> - </li> - </ul> - <p style="margin-top: -7px;">Any links, images or other markup will be kept as plain text. Also, free speech is good and all, but please keep it civil. Sufficient JavaScript support will be required to bind shortkeys. Please type the markup manually if you are on an older browser.</p> + <br> + <a id="markup-tips" onclick="toggleTips()" style="cursor: pointer;">Text Markup Tips ></a> + <div id="tips" style="display: none;"> + <ul style="list-style-type: disc; margin: 0;padding: 0; margin: 5px 0px 0px 30px;"> + <li>Wrap text in double underscores (__) to make it <i>italic</i>. + <br> + e.g. <code>__italic__</code> + shortkey: <kbd>Ctrl or Cmd + I</kbd> + <br><br> + </li> + <li>Wrap text in double asterisks (**) to make it <b>bold</b>. + <br> + e.g. <code>**bold**</code> + shortkey: <kbd>Ctrl or Cmd + B</kbd> + <br><br> + </li> + <li>Wrap text in double tildes (~~) to <s>strikethrough</s> it. + <br> + e.g. <code>~~strikethrough~~</code> + shortkey: <kbd>Ctrl or Cmd + D</kbd> + <br><br> + </li> + <li>Wrap text in triple backticks (```) to make it a code block. + <br> + e.g. <code>```code block```</code>, + shortkey: <kbd>Ctrl or Cmd + K</kbd> + <br><br> + </li> + </ul> + <p style="margin-top: -7px;">Any links, images or other markup will be kept as plain text. Also, free speech is good and all, but please keep it civil. Sufficient JavaScript support will be required to bind shortkeys. Please type the markup manually if you are on an older browser.</p> + </div> </div> </div> {% else %} @@ -115,6 +118,15 @@ document.getElementById('edit-form-' + id).style.display = 'none'; } + function toggleTips() { + var tips = document.getElementById('tips'); + if (tips.style.display == 'none') { + tips.style.display = 'block'; + } else { + tips.style.display = 'none'; + } + } + // We are aiming to keep the JS to ES3 for compatibility with older browsers. // Get all textareas and bind the shortkeys. var textareas = document.getElementsByTagName('textarea'); diff --git a/users/urls.py b/users/urls.py index 02a7e302..1450653e 100644 --- a/users/urls.py +++ b/users/urls.py @@ -12,6 +12,7 @@ urlpatterns = [ path('/verifyemail/<uidb64>/<token>', views.verify_email, name='verifyemail'), path('/sendchangeuseremail', views.send_change_user_email, name='sendchangeuseremail'), path('/changeemail/<uidb64>/<token>', views.change_email, name='changeemail'), + path('updateavatar', views.update_avatar, name='updateavatar'), ] # Configure Admin Site diff --git a/users/views.py b/users/views.py index 05d379ff..5027bd64 100644 --- a/users/views.py +++ b/users/views.py @@ -51,7 +51,6 @@ def update_user(request): first_name = request.POST['firstname'] last_name = request.POST['lastname'] location = request.POST['location'] - gravatar_email = request.POST['gravatarEmail'] bio = request.POST['bio'] is_public = False email_public = False @@ -69,13 +68,12 @@ def update_user(request): try: user_profile = UserProfile.objects.get(user=username) user_profile.location = location - user_profile.gravatar_email = gravatar_email user_profile.bio = bio user_profile.is_public = is_public user_profile.email_public = email_public user_profile.save() except UserProfile.DoesNotExist: - user_profile = UserProfile(user=username, location=location, gravatar_email=gravatar_email, bio=bio, is_public=is_public, email_public=email_public) + user_profile = UserProfile(user=username, location=location, bio=bio, is_public=is_public, email_public=email_public) user_profile.save() messages.success(request, 'Profile was successfully updated!') return redirect('blog:account') @@ -83,6 +81,22 @@ def update_user(request): messages.error(request, 'Unable to update profile! Please try again later.') return redirect('blog:home') +def update_avatar(request): + user = request.user + if user is not None: + if request.method == 'POST': + user_profile = UserProfile.objects.get(user=user) + user_profile.avatar_url = request.POST['avatar'] + user_profile.save() + messages.success(request, 'Avatar was successfully updated!') + return redirect('blog:account') + else: + messages.error(request, 'Unable to update avatar! Please try again later.') + return redirect('blog:home') + else: + messages.error(request, 'You must be logged in to update your avatar!') + return redirect('blog:home') + def change_password(request): username = request.user |
