From 1913c6aa68652752f7077aa1e4516a23fb67a5cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C5=BE=C3=ADlek?= Date: Tue, 21 Apr 2020 10:26:03 +0200 Subject: [PATCH] User profile BS --- yadc/__init__.py | 12 ++---- yadc/assets/css/base-types.scss | 2 +- yadc/assets/css/default.scss | 13 +++++- yadc/assets/css/main.scss | 2 + yadc/assets/js/taginput.js | 12 ------ yadc/bp/manage.py | 24 ++++++------ yadc/bp/post.py | 23 ++++------- yadc/bp/user.py | 18 +++++++-- yadc/forms.py | 1 - yadc/models.py | 10 ++--- yadc/static/all.css | 2 +- yadc/static/all.js | 12 ------ yadc/templates/_includes.html | 28 +------------ yadc/templates/layout/settings.html | 2 +- yadc/templates/user/profile.html | 61 ++++++++++++++++++++--------- 15 files changed, 104 insertions(+), 118 deletions(-) diff --git a/yadc/__init__.py b/yadc/__init__.py index 6408fb5..df8ad05 100644 --- a/yadc/__init__.py +++ b/yadc/__init__.py @@ -13,7 +13,6 @@ login = LoginManager() assets = AssetsEnvironment() def create_app(): - app = Flask(__name__, instance_relative_config=True) app.config.from_mapping(POST_UPLOADS=os.path.join(app.instance_path, 'post'), SQLALCHEMY_TRACK_MODIFICATIONS=False) @@ -76,14 +75,9 @@ def create_app(): from yadc import models as m - app = create_app() @app.shell_context_processor def make_shell_context(): - ctxt = {'db': db} - - for mdl in [m.User, m.Post, m.Tag, m.Comment]: - ctxt[mdl.__name__] = mdl - - return ctxt - # return {'db': db, 'User': models.User, 'Post': models.Post, 'Tag': models.Tag, 'Comment': models.Comment} \ No newline at end of file + return dict(db=db, **{mdl.__name__:mdl for mdl in ( + m.User, m.Post, m.Tag, m.Comment + )}) \ No newline at end of file diff --git a/yadc/assets/css/base-types.scss b/yadc/assets/css/base-types.scss index 12222f0..e288561 100644 --- a/yadc/assets/css/base-types.scss +++ b/yadc/assets/css/base-types.scss @@ -53,7 +53,7 @@ h2 { // font-size: 1.3em; } h3 { - margin: 0; + // margin: 0; margin-bottom: .5em; font-size: 1.3em; diff --git a/yadc/assets/css/default.scss b/yadc/assets/css/default.scss index 1fa1195..a3b1c99 100644 --- a/yadc/assets/css/default.scss +++ b/yadc/assets/css/default.scss @@ -1,7 +1,7 @@ .main-wrap { margin: 0 auto; - max-width: 1300px; + max-width: $max-content-width; padding: $main-wrap-padding; padding-top: 0; @@ -213,6 +213,17 @@ } } } + .user-main, .user-comments { + flex-grow: 1; + flex-basis: 0; + padding: 10px; + + // border: 1px solid red; + + .comment-container { + // border: 1px solid white; + } + } section.manage-profile { // @include media($bp-desktop) { diff --git a/yadc/assets/css/main.scss b/yadc/assets/css/main.scss index 8cd70c5..0116762 100644 --- a/yadc/assets/css/main.scss +++ b/yadc/assets/css/main.scss @@ -18,6 +18,8 @@ $main-wrap-padding: 8px; // $sidepanel-width: 14rem; $sidepanel-width: 18rem; +$max-content-width: 1300px; + @import "base-types"; @import "header"; @import "default"; diff --git a/yadc/assets/js/taginput.js b/yadc/assets/js/taginput.js index 81d6145..601ffdd 100644 --- a/yadc/assets/js/taginput.js +++ b/yadc/assets/js/taginput.js @@ -1,15 +1,3 @@ -// // https://stackoverflow.com/questions/8486099/how-do-i-parse-a-url-query-parameters-in-javascript -// function getJsonFromUrl(url) { -// if(!url) url = location.search; -// var query = url.substr(1); -// var result = {}; -// query.split("&").forEach(function(part) { -// var item = part.split("="); -// result[item[0]] = decodeURIComponent(item[1]); -// }); -// return result; -// } - function create_selection_tag(tagname) { // CLEAR let tag = document.createElement("a") tag.classList.add("tagselected") diff --git a/yadc/bp/manage.py b/yadc/bp/manage.py index 03af981..ed222f6 100644 --- a/yadc/bp/manage.py +++ b/yadc/bp/manage.py @@ -63,21 +63,21 @@ def manage_tags(page): return render_template('manage/tags.html', tags=tags, elements=tags.items, createform=TagForm()) -@bp.route('/comments', defaults={'page': 1}) -@bp.route('/comments/') -@login_required -@moderator_required -def manage_comments(page): - comments = Comment.query.order_by(Comment.updated).paginate(page, current_app.config.get('MANAGE_PER_PAGE')) +# @bp.route('/comments', defaults={'page': 1}) +# @bp.route('/comments/') +# @login_required +# @moderator_required +# def manage_comments(page): +# comments = Comment.query.order_by(Comment.updated).paginate(page, current_app.config.get('MANAGE_PER_PAGE')) - # for comment in comments.items: - # comment.editform = CommentForm( - # id=comment.id, - # content=comment.content, +# # for comment in comments.items: +# # comment.editform = CommentForm( +# # id=comment.id, +# # content=comment.content, - # ) +# # ) - return render_template('manage/comments.html', tags=comments, elements=comments.items) +# return render_template('manage/comments.html', tags=comments, elements=comments.items) # ONLY THROUGH MANAGEMENT diff --git a/yadc/bp/post.py b/yadc/bp/post.py index 574fe6b..e6da54a 100644 --- a/yadc/bp/post.py +++ b/yadc/bp/post.py @@ -18,13 +18,8 @@ bp = Blueprint('post', __name__) @bp.route('/') def posts(page): def tags_prepare(posts): - tags = db.session.query(Tag, func.array_agg(Post.id)).join(Tag.posts).filter(Post.id.in_([p.id for p in posts])).group_by(Tag.id).all() - - for tag,p_ids in tags: - tag.count = len(p_ids) - tag.post_ids = p_ids - - tags = [t[0] for t in tags] + tags = db.session.query(Tag, func.count(Post.id), func.array_agg(Post.id)).join(Tag.posts).filter(Post.id.in_([p.id for p in posts])).group_by(Tag.id).all() + tags = [tag for tag, tag.count, tag.post_ids in tags] tags.sort(key=lambda x: (x.category.value, x.content) ) return tags @@ -35,7 +30,6 @@ def posts(page): f_rating = {r.name : r for r in RATING}.get(request.args.get('rating')) session['enforced_rating'] = f_rating.name if f_rating else None - # flash(f_rating.name if f_rating else None) if current_user.is_authenticated and current_user.rating is RATING.explicit and f_rating is RATING.explicit: return redirect(url_for('.posts')) # Fookin hack to fix the state after user's switch to RATING.explicit @@ -45,8 +39,6 @@ def posts(page): m_ratings = f_rating.matched if f_rating else RATING.safe.matched # filter user's blacklist - # if current_user.is_authenticated: - # f_tags = list(t for t in f_tags if t not in [tb.content for tb in current_user.tag_blacklist]) blacklist_tags = [tb.content for tb in current_user.tag_blacklist] if current_user.is_authenticated else None posts_query = Post.query @@ -72,9 +64,10 @@ def post_show(id): # return redirect(url_for('.posts')) tags_count = db.session.query(Tag, func.count(Post.id)).join(Tag.posts).filter(Post.id==id).join(aliased(Post), Tag.posts).group_by(Tag).all() - for tag,tag.count in tags_count: - # tag.endpoint = query_replace(dict(**session_rating(), tags=tag.content), url_for('.posts')) - pass + # for tag,tag.count in tags_count: + # # tag.endpoint = query_replace(dict(**session_rating(), tags=tag.content), url_for('.posts')) + # pass + tags = [tag for tag,tag.count in tags_count] comments = db.session.query(Comment).filter_by(post=post).filter_by(visible=True).order_by(Comment.id).all() @@ -84,14 +77,14 @@ def post_show(id): return render_template( 'post/post.html', post=post, - tags=post.tags, + tags=tags, comments=comments, editform=PostForm( id=post.id, referer=post_show.__name__, source=post.source, parent=post.parent_id, - tags=' '.join(t.content for t in post.tags), + tags=' '.join(t.content for t in tags), rating=post.rating, status=post.status ), diff --git a/yadc/bp/user.py b/yadc/bp/user.py index a1f8cd7..86079f5 100644 --- a/yadc/bp/user.py +++ b/yadc/bp/user.py @@ -1,7 +1,7 @@ from flask import (Blueprint, abort, current_app, flash, redirect, render_template, request, send_from_directory, url_for) from flask_login import current_user, login_required -from yadc.forms import ChangeUserInfoForm, ChangePassForm, ChangeMailForm, ChangeUserRatingForm, ChangeTagBlacklistForm, DeleteUserDataForm +from yadc.forms import ChangeUserInfoForm, ChangePassForm, ChangeMailForm, ChangeUserRatingForm, ChangeTagBlacklistForm, DeleteUserDataForm, CommentForm from yadc import db from yadc.models import User, Post, Comment, Tag @@ -12,7 +12,19 @@ bp = Blueprint('user', __name__) @bp.route('/@') def profile(username): user = User.query.filter_by(username=username).first_or_404() - return render_template('user/profile.html', user=user) + last_comments = Comment.query.filter_by(user=user).order_by(Comment.id).limit(5).all() + + for comment in last_comments: + comment.editform = CommentForm(id=comment.id, content=comment.content) + + return render_template( + 'user/profile.html', + user=user, + comments=last_comments, + post_count=Post.query.filter_by(author=user).count(), + comment_count=Comment.query.filter_by(user=user).count(), + approved_count=Post.query.filter_by(approver=user).count() + ) @bp.route('/settings') @login_required @@ -25,7 +37,7 @@ def settings(): rating_form=ChangeUserRatingForm(rating=current_user.rating.name), tags_form=ChangeTagBlacklistForm(tags=' '.join(t.content for t in current_user.tag_blacklist)), delete_form=DeleteUserDataForm() - ) + ) @bp.route('/change_info', methods=['POST']) @login_required diff --git a/yadc/forms.py b/yadc/forms.py index 97d054b..62be182 100644 --- a/yadc/forms.py +++ b/yadc/forms.py @@ -87,7 +87,6 @@ class UploadForm(CSRFForm): raise ValidationError('Image is corrupted.') fileinfo = Post.fileinfo(file) - post = Post.query.filter_by(md5=fileinfo['md5']).first() if post is not None: raise ValidationError('Image with same hash already exists. Reposting is not allowed.') diff --git a/yadc/models.py b/yadc/models.py index 0940158..1173192 100644 --- a/yadc/models.py +++ b/yadc/models.py @@ -16,13 +16,13 @@ from yadc import db, login, utils class OP_LEVEL(enum.Enum): user = 0 - creator = 1 + creator = 1 # IS HE CREATOR OR NOT? moderator = 5 admin = 9 class USER_STATUS(enum.Enum): active = 0 - inactive = 1 + # inactive = 1 banned = 5 class FILETYPE(enum.Enum): @@ -114,8 +114,6 @@ class User(UserMixin, TimestampMixin, db.Model): self.pass_hash = generate_password_hash(password, salt_length=16) def check_password(self, password): - # if self.pass_hash is None: - # return True if self.pass_hash is None: return False return check_password_hash(self.pass_hash, password) @@ -132,7 +130,7 @@ class User(UserMixin, TimestampMixin, db.Model): self.user_status is USER_STATUS.active @property - def is_author(self): + def is_uploader(self): return len(self.authored_posts) > 0 @property @@ -343,7 +341,7 @@ class Comment(TimestampMixin, db.Model): deleted = db.Column(db.Boolean, default=False) post_id = db.Column(db.Integer, db.ForeignKey('post.id')) - post = db.relationship('Post', backref=db.backref('comments', order_by='Comment.id', lazy=True)) + post = db.relationship('Post', backref=db.backref('comments', lazy=True)) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) user = db.relationship('User', backref=db.backref('comments', lazy=True)) diff --git a/yadc/static/all.css b/yadc/static/all.css index c866084..aad55ba 100644 --- a/yadc/static/all.css +++ b/yadc/static/all.css @@ -1 +1 @@ -.flash_msgs{display:flex;flex-flow:column-reverse nowrap;position:fixed;z-index:20;bottom:0;right:0;margin:0;padding:10px;font-size:.9em;pointer-events:none}.flash_msgs>li{width:250px;padding:10px;list-style-type:none;background-color:#000c;overflow:hidden;opacity:0;animation:fade 7s normal}.flash_msgs>li:not(:first-child){margin-bottom:10px}@keyframes fade{0%,100%{opacity:0}20%,80%{opacity:1}}.flash_msgs>li.error{background-color:#500c}h2{margin:0;margin-bottom:.5em}h3{margin:0;margin-bottom:.5em;font-size:1.3em}h4{margin:0;margin-bottom:.8em;margin-top:.4em}.oneline-space{height:1em}.comment-form{margin-left:10px;max-width:500px}.comment-form input:required{box-shadow:none}.editingable:not(.time-to-edit) .edit{display:none!important}.editingable:not(.time-to-edit):hover .jsoff-show.edit{display:initial!important}.editingable:not(.time-to-edit):hover .jsoff-show.notedit{display:none!important}.editingable:not(.time-to-edit) .jsoff-hide.edit,.editingable:not(.time-to-edit) .jsoff-hide.notedit{display:none!important}.editingable.time-to-edit .notedit{display:none!important}input[type=text],input[type=password],textarea{background:#444a;border:1px solid #444;color:inherit;display:block;padding:.5em}input[type=text],input[type=password]{width:100%}textarea{resize:vertical;width:100%}input[type=submit]{background:#444a;border:2px solid #666a;border-radius:4px;color:inherit;padding:.4em 1.8em}input[type=submit]:active{background:#000a;border:2px solid #444a}label{padding:.4em}.baseform input[type=text],.baseform input[type=password],.baseform textarea,.pageform input[type=text],.pageform input[type=password],.pageform textarea{width:100%}.baseform input[type=checkbox],.pageform input[type=checkbox]{margin:.5em}.baseform input[type=submit],.pageform input[type=submit]{margin:.2em}.baseform>input,.baseform>textarea,.baseform>div,.baseform form>input,.baseform form>textarea,.baseform form>div,.pageform>input,.pageform>textarea,.pageform>div,.pageform form>input,.pageform form>textarea,.pageform form>div{margin:.8em 0}.baseform div.row,.pageform div.row{display:flex;align-items:center}.baseform div.row.stretch,.pageform div.row.stretch{justify-content:space-between}.baseform div.row label,.pageform div.row label{padding:0;margin-left:.2em;margin-right:.6em}.baseform ul,.pageform ul{padding:0;margin:0}.baseform ul li,.pageform ul li{list-style-type:none}.pageform{padding:1em;width:300px;margin:0 auto}.tag-input .tag-suggester{width:100%;position:relative}.tag-input .tag-suggester input[type=text]{margin:.3em 0}.tag-input .tag-suggester>.suggest-dropdown{display:flex;align-items:start;width:100%;top:100%;position:absolute;z-index:10;overflow:auto;background-color:#2d2d2de0}.tag-input .tag-suggester>.suggest-dropdown:not(:empty){padding:.2em}.tag-input .tag-suggester>.suggest-dropdown>a.sug-sel{background-color:#242424}.tag-container{display:flex;flex-flow:row wrap}.tag-container:empty{display:none}.tag-container>a{display:flex;justify-content:space-between;overflow:hidden;align-items:baseline;margin:.2em;padding:.35em .6em;border-radius:4px;background-color:#121212ff;cursor:pointer}.tag-container>a .content{margin:0 .4em;flex-grow:1;flex-basis:100%;word-break:break-word;overflow-wrap:anywhere}.tag-container>a .tag-icon,.tag-container>a .tag-right{align-self:center}.tag-container>a .count{font-size:.8em;margin-right:.4em}.tag-container>a>*{pointer-events:none}.tag-container>a:not(:hover) span.close{opacity:0}.tag-container>a:not(:hover) span.plus{opacity:0}.tag-container>a.tagselected{background-color:#400808ff}.tag-container>a.tag_hide{display:none}.comment-container{max-width:500px}.comment-container article.comment{overflow:hidden;margin:.4em .4em;padding:.4em .4em}.comment-container article.comment p,.comment-container article.comment textarea{margin:0}.comment-container article.comment p.deleted,.comment-container article.comment textarea.deleted{color:red}.comment-container article.comment .comment-head{display:flex;justify-content:space-between;align-items:baseline}.comment-container article.comment .comment-head h4{margin:0;padding:.4em}.comment-container article.comment .comment-head a,.comment-container article.comment .comment-head label{cursor:pointer}.comment-container article.comment .comment-head .controls{display:flex}.comment-container article.comment .comment-head .controls label>input{display:none}.comment-container article.comment .comment-editform p{padding:.5em}.comment-container article.comment .comment-editform textarea{font-size:inherit;font-family:inherit;border:none}header{display:flex;align-items:baseline;padding:0 10px;background-color:#222}header>a.logo{font-size:2em;margin:6px}@media(max-width:559px){header{position:relative}}header>nav{flex-grow:1;display:flex}header>nav>._overlay{display:none}@media(max-width:559px){header>nav{display:none}header>nav._drop{display:flex;flex-flow:column nowrap;position:absolute;margin:0;top:100%;left:0;right:0;z-index:10;background-color:#111d}header>nav>a,header>nav a#user-menu,header>nav .user_dropdown>a{padding:12px;padding-left:24px}header>nav>a:hover,header>nav>a:active,header>nav a#user-menu:hover,header>nav a#user-menu:active,header>nav .user_dropdown>a:hover,header>nav .user_dropdown>a:active{background-color:#333}header>nav .user::before{content:"";display:block;border-top:1px solid grey;margin:2px 12px}header>nav .user #user-menu{display:block}header>nav .user .user_dropdown{display:flex;flex-flow:column nowrap}header>nav>._overlay{display:block;position:fixed;width:100%;height:100%;z-index:-1;background-color:#0006}html.oh{overflow:hidden}}@media(min-width:560px){header>nav{margin:0 5px;align-items:center}header>nav>*{margin:0 5px;padding:6px 0}header>nav>.user{padding:0;margin-left:auto;margin-right:0;position:relative}header>nav>.user #user-menu{display:block;padding:6px 10px}header>nav>.user .user_dropdown{display:none}header>nav>.user .user_dropdown a{padding:10px}header>nav>.user .user_dropdown a:hover{background-color:#333}header>nav>.user:hover>.user_dropdown{display:flex;flex-flow:column nowrap;position:absolute;margin:0;top:100%;right:0;z-index:10;background-color:#111d}}header>#nav-menu{display:none}@media(max-width:559px){header>#nav-menu{display:block;margin:5px;margin-left:auto;padding:0 2px;align-self:center;font-size:2em;cursor:pointer}}.main-wrap{margin:0 auto;max-width:1300px;padding:8px;padding-top:0;padding-bottom:0;display:flex}@media(min-width:900px){.main-wrap{flex-flow:row nowrap}}@media(max-width:899px){.main-wrap{flex-flow:column nowrap}}@media(max-width:899px){.main-wrap{overflow:visible}}.main-wrap .important-subwrap{display:flex;flex-flow:column nowrap;flex-grow:1;overflow:visible}@media(max-width:899px){.main-wrap .important-subwrap{display:contents}}.main-wrap>section.sidepanel{flex-shrink:0;padding:10px}@media(min-width:900px){.main-wrap>section.sidepanel{width:18rem}}.main-wrap>section.sidepanel article:not(:last-child){margin-bottom:10px}@media(max-width:899px){.main-wrap>section.sidepanel article.tags .tag-container,.main-wrap>section.sidepanel article.post-edit .tag-container{flex-flow:row wrap}}@media(min-width:900px){.main-wrap>section.sidepanel article.tags .tag-container,.main-wrap>section.sidepanel article.post-edit .tag-container{flex-flow:column nowrap;align-items:start}.main-wrap>section.sidepanel article.tags .suggest-dropdown,.main-wrap>section.sidepanel article.post-edit .suggest-dropdown{flex-flow:row wrap}.main-wrap>section.sidepanel article.tags .suggest-dropdown a,.main-wrap>section.sidepanel article.post-edit .suggest-dropdown a{width:100%}}.main-wrap>section.sidepanel article.rating ul{padding:0}.main-wrap>section.sidepanel article.rating ul li{list-style-type:none}.main-wrap>section.sidepanel article.post-desc{display:flex;flex-flow:column nowrap;font-size:.9em}.main-wrap>section.sidepanel article.post-desc .source>a{word-break:break-all}.main-wrap>section.sidepanel article.post-desc>img{display:block;max-width:128px}.main-wrap>section.sidepanel article.sidenav>a{display:block;padding:.3em 1em}@media(min-width:900px){.main-wrap section:not(.sidepanel){width:100%}}.main-wrap section.post-list{overflow:hidden}@media(max-width:559px){.main-wrap section.post-list{margin-left:-8px;margin-right:-8px}}.main-wrap section.post-list .posts{display:flex;flex-flow:row wrap}@media(max-width:899px){.main-wrap section.post-list .posts{margin-left:-8px;margin-right:-8px}}.main-wrap section.post-list .posts::after{content:"";flex:10000 0 350px}.main-wrap section.post-list .posts>figure{position:relative;margin:8px}.main-wrap section.post-list .posts>figure img{display:block;width:100%;height:100%;transition:.2s ease}.main-wrap section.post-list .posts>figure:hover img{opacity:.7}@media(min-width:900px){.main-wrap section.post-single{padding:8px}}@media(max-width:899px){.main-wrap section.post-single{order:-1;margin-bottom:8px}}@media(max-width:559px){.main-wrap section.post-single{margin-left:-8px;margin-right:-8px}}.main-wrap section.post-single img{display:block;max-width:100%}.main-wrap section.comments{padding:10px}.main-wrap section.management-table{overflow-x:auto}.main-wrap section.management-table table{margin:0 auto}.main-wrap section.management-table tr{background-color:#303030}.main-wrap section.management-table tr th,.main-wrap section.management-table tr td{padding:6px 10px}.main-wrap section.management-table tr th{background-color:#606060}.main-wrap section.management-table tr label>input{display:none}.main-wrap section.management-table tr .fa{padding:4px 4px;align-self:center;font-size:1.5em;cursor:pointer}.main-wrap section.manage-profile>.baseform{margin:0 10px;margin-bottom:15px;max-width:500px}.main-wrap .pagin{margin:10px 0;display:flex;flex-flow:row nowrap;justify-content:center}.main-wrap .pagin>a{display:block;background-color:#0005;padding:8px 12px;margin:0 2px}footer{padding:10px;text-align:center}*{box-sizing:border-box}body{margin:0;font-family:Verdana,Geneva,Tahoma,sans-serif;background-color:#222;color:#fff}a{color:#bbb;text-decoration:none}a:hover{color:#909090;text-decoration:none} \ No newline at end of file +.flash_msgs{display:flex;flex-flow:column-reverse nowrap;position:fixed;z-index:20;bottom:0;right:0;margin:0;padding:10px;font-size:.9em;pointer-events:none}.flash_msgs>li{width:250px;padding:10px;list-style-type:none;background-color:#000c;overflow:hidden;opacity:0;animation:fade 7s normal}.flash_msgs>li:not(:first-child){margin-bottom:10px}@keyframes fade{0%,100%{opacity:0}20%,80%{opacity:1}}.flash_msgs>li.error{background-color:#500c}h2{margin:0;margin-bottom:.5em}h3{margin-bottom:.5em;font-size:1.3em}h4{margin:0;margin-bottom:.8em;margin-top:.4em}.oneline-space{height:1em}.comment-form{margin-left:10px;max-width:500px}.comment-form input:required{box-shadow:none}.editingable:not(.time-to-edit) .edit{display:none!important}.editingable:not(.time-to-edit):hover .jsoff-show.edit{display:initial!important}.editingable:not(.time-to-edit):hover .jsoff-show.notedit{display:none!important}.editingable:not(.time-to-edit) .jsoff-hide.edit,.editingable:not(.time-to-edit) .jsoff-hide.notedit{display:none!important}.editingable.time-to-edit .notedit{display:none!important}input[type=text],input[type=password],textarea{background:#444a;border:1px solid #444;color:inherit;display:block;padding:.5em}input[type=text],input[type=password]{width:100%}textarea{resize:vertical;width:100%}input[type=submit]{background:#444a;border:2px solid #666a;border-radius:4px;color:inherit;padding:.4em 1.8em}input[type=submit]:active{background:#000a;border:2px solid #444a}label{padding:.4em}.baseform input[type=text],.baseform input[type=password],.baseform textarea,.pageform input[type=text],.pageform input[type=password],.pageform textarea{width:100%}.baseform input[type=checkbox],.pageform input[type=checkbox]{margin:.5em}.baseform input[type=submit],.pageform input[type=submit]{margin:.2em}.baseform>input,.baseform>textarea,.baseform>div,.baseform form>input,.baseform form>textarea,.baseform form>div,.pageform>input,.pageform>textarea,.pageform>div,.pageform form>input,.pageform form>textarea,.pageform form>div{margin:.8em 0}.baseform div.row,.pageform div.row{display:flex;align-items:center}.baseform div.row.stretch,.pageform div.row.stretch{justify-content:space-between}.baseform div.row label,.pageform div.row label{padding:0;margin-left:.2em;margin-right:.6em}.baseform ul,.pageform ul{padding:0;margin:0}.baseform ul li,.pageform ul li{list-style-type:none}.pageform{padding:1em;width:300px;margin:0 auto}.tag-input .tag-suggester{width:100%;position:relative}.tag-input .tag-suggester input[type=text]{margin:.3em 0}.tag-input .tag-suggester>.suggest-dropdown{display:flex;align-items:start;width:100%;top:100%;position:absolute;z-index:10;overflow:auto;background-color:#2d2d2de0}.tag-input .tag-suggester>.suggest-dropdown:not(:empty){padding:.2em}.tag-input .tag-suggester>.suggest-dropdown>a.sug-sel{background-color:#242424}.tag-container{display:flex;flex-flow:row wrap}.tag-container:empty{display:none}.tag-container>a{display:flex;justify-content:space-between;overflow:hidden;align-items:baseline;margin:.2em;padding:.35em .6em;border-radius:4px;background-color:#121212ff;cursor:pointer}.tag-container>a .content{margin:0 .4em;flex-grow:1;flex-basis:100%;word-break:break-word;overflow-wrap:anywhere}.tag-container>a .tag-icon,.tag-container>a .tag-right{align-self:center}.tag-container>a .count{font-size:.8em;margin-right:.4em}.tag-container>a>*{pointer-events:none}.tag-container>a:not(:hover) span.close{opacity:0}.tag-container>a:not(:hover) span.plus{opacity:0}.tag-container>a.tagselected{background-color:#400808ff}.tag-container>a.tag_hide{display:none}.comment-container{max-width:500px}.comment-container article.comment{overflow:hidden;margin:.4em .4em;padding:.4em .4em}.comment-container article.comment p,.comment-container article.comment textarea{margin:0}.comment-container article.comment p.deleted,.comment-container article.comment textarea.deleted{color:red}.comment-container article.comment .comment-head{display:flex;justify-content:space-between;align-items:baseline}.comment-container article.comment .comment-head h4{margin:0;padding:.4em}.comment-container article.comment .comment-head a,.comment-container article.comment .comment-head label{cursor:pointer}.comment-container article.comment .comment-head .controls{display:flex}.comment-container article.comment .comment-head .controls label>input{display:none}.comment-container article.comment .comment-editform p{padding:.5em}.comment-container article.comment .comment-editform textarea{font-size:inherit;font-family:inherit;border:none}header{display:flex;align-items:baseline;padding:0 10px;background-color:#222}header>a.logo{font-size:2em;margin:6px}@media(max-width:559px){header{position:relative}}header>nav{flex-grow:1;display:flex}header>nav>._overlay{display:none}@media(max-width:559px){header>nav{display:none}header>nav._drop{display:flex;flex-flow:column nowrap;position:absolute;margin:0;top:100%;left:0;right:0;z-index:10;background-color:#111d}header>nav>a,header>nav a#user-menu,header>nav .user_dropdown>a{padding:12px;padding-left:24px}header>nav>a:hover,header>nav>a:active,header>nav a#user-menu:hover,header>nav a#user-menu:active,header>nav .user_dropdown>a:hover,header>nav .user_dropdown>a:active{background-color:#333}header>nav .user::before{content:"";display:block;border-top:1px solid grey;margin:2px 12px}header>nav .user #user-menu{display:block}header>nav .user .user_dropdown{display:flex;flex-flow:column nowrap}header>nav>._overlay{display:block;position:fixed;width:100%;height:100%;z-index:-1;background-color:#0006}html.oh{overflow:hidden}}@media(min-width:560px){header>nav{margin:0 5px;align-items:center}header>nav>*{margin:0 5px;padding:6px 0}header>nav>.user{padding:0;margin-left:auto;margin-right:0;position:relative}header>nav>.user #user-menu{display:block;padding:6px 10px}header>nav>.user .user_dropdown{display:none}header>nav>.user .user_dropdown a{padding:10px}header>nav>.user .user_dropdown a:hover{background-color:#333}header>nav>.user:hover>.user_dropdown{display:flex;flex-flow:column nowrap;position:absolute;margin:0;top:100%;right:0;z-index:10;background-color:#111d}}header>#nav-menu{display:none}@media(max-width:559px){header>#nav-menu{display:block;margin:5px;margin-left:auto;padding:0 2px;align-self:center;font-size:2em;cursor:pointer}}.main-wrap{margin:0 auto;max-width:1300px;padding:8px;padding-top:0;padding-bottom:0;display:flex}@media(min-width:900px){.main-wrap{flex-flow:row nowrap}}@media(max-width:899px){.main-wrap{flex-flow:column nowrap}}@media(max-width:899px){.main-wrap{overflow:visible}}.main-wrap .important-subwrap{display:flex;flex-flow:column nowrap;flex-grow:1;overflow:visible}@media(max-width:899px){.main-wrap .important-subwrap{display:contents}}.main-wrap>section.sidepanel{flex-shrink:0;padding:10px}@media(min-width:900px){.main-wrap>section.sidepanel{width:18rem}}.main-wrap>section.sidepanel article:not(:last-child){margin-bottom:10px}@media(max-width:899px){.main-wrap>section.sidepanel article.tags .tag-container,.main-wrap>section.sidepanel article.post-edit .tag-container{flex-flow:row wrap}}@media(min-width:900px){.main-wrap>section.sidepanel article.tags .tag-container,.main-wrap>section.sidepanel article.post-edit .tag-container{flex-flow:column nowrap;align-items:start}.main-wrap>section.sidepanel article.tags .suggest-dropdown,.main-wrap>section.sidepanel article.post-edit .suggest-dropdown{flex-flow:row wrap}.main-wrap>section.sidepanel article.tags .suggest-dropdown a,.main-wrap>section.sidepanel article.post-edit .suggest-dropdown a{width:100%}}.main-wrap>section.sidepanel article.rating ul{padding:0}.main-wrap>section.sidepanel article.rating ul li{list-style-type:none}.main-wrap>section.sidepanel article.post-desc{display:flex;flex-flow:column nowrap;font-size:.9em}.main-wrap>section.sidepanel article.post-desc .source>a{word-break:break-all}.main-wrap>section.sidepanel article.post-desc>img{display:block;max-width:128px}.main-wrap>section.sidepanel article.sidenav>a{display:block;padding:.3em 1em}@media(min-width:900px){.main-wrap section:not(.sidepanel){width:100%}}.main-wrap section.post-list{overflow:hidden}@media(max-width:559px){.main-wrap section.post-list{margin-left:-8px;margin-right:-8px}}.main-wrap section.post-list .posts{display:flex;flex-flow:row wrap}@media(max-width:899px){.main-wrap section.post-list .posts{margin-left:-8px;margin-right:-8px}}.main-wrap section.post-list .posts::after{content:"";flex:10000 0 350px}.main-wrap section.post-list .posts>figure{position:relative;margin:8px}.main-wrap section.post-list .posts>figure img{display:block;width:100%;height:100%;transition:.2s ease}.main-wrap section.post-list .posts>figure:hover img{opacity:.7}@media(min-width:900px){.main-wrap section.post-single{padding:8px}}@media(max-width:899px){.main-wrap section.post-single{order:-1;margin-bottom:8px}}@media(max-width:559px){.main-wrap section.post-single{margin-left:-8px;margin-right:-8px}}.main-wrap section.post-single img{display:block;max-width:100%}.main-wrap section.comments{padding:10px}.main-wrap section.management-table{overflow-x:auto}.main-wrap section.management-table table{margin:0 auto}.main-wrap section.management-table tr{background-color:#303030}.main-wrap section.management-table tr th,.main-wrap section.management-table tr td{padding:6px 10px}.main-wrap section.management-table tr th{background-color:#606060}.main-wrap section.management-table tr label>input{display:none}.main-wrap section.management-table tr .fa{padding:4px 4px;align-self:center;font-size:1.5em;cursor:pointer}.main-wrap .user-main,.main-wrap .user-comments{flex-grow:1;flex-basis:0;padding:10px}.main-wrap section.manage-profile>.baseform{margin:0 10px;margin-bottom:15px;max-width:500px}.main-wrap .pagin{margin:10px 0;display:flex;flex-flow:row nowrap;justify-content:center}.main-wrap .pagin>a{display:block;background-color:#0005;padding:8px 12px;margin:0 2px}footer{padding:10px;text-align:center}*{box-sizing:border-box}body{margin:0;font-family:Verdana,Geneva,Tahoma,sans-serif;background-color:#222;color:#fff}a{color:#bbb;text-decoration:none}a:hover{color:#909090;text-decoration:none} \ No newline at end of file diff --git a/yadc/static/all.js b/yadc/static/all.js index 7ff472d..960e118 100644 --- a/yadc/static/all.js +++ b/yadc/static/all.js @@ -86,18 +86,6 @@ document.getElementById("user-menu").addEventListener('click', (ev) => { drop.classList.remove("_drop") } }) -// // https://stackoverflow.com/questions/8486099/how-do-i-parse-a-url-query-parameters-in-javascript -// function getJsonFromUrl(url) { -// if(!url) url = location.search; -// var query = url.substr(1); -// var result = {}; -// query.split("&").forEach(function(part) { -// var item = part.split("="); -// result[item[0]] = decodeURIComponent(item[1]); -// }); -// return result; -// } - function create_selection_tag(tagname) { // CLEAR let tag = document.createElement("a") tag.classList.add("tagselected") diff --git a/yadc/templates/_includes.html b/yadc/templates/_includes.html index d7e71f4..a412820 100644 --- a/yadc/templates/_includes.html +++ b/yadc/templates/_includes.html @@ -21,37 +21,13 @@ {% endmacro %} - -{% macro render_comments() %} -
- {% for comment in comments %} -
-
-

{{ comment.user.username }}

- {% if comment.can_edit %} - edit - {% endif %} -
- {% if not comment.deleted %} -

{{ comment.content }}

- {% else %} -

{{ comment.delete_reason }}

- {% endif %} -
- {% endfor %} - {% if not comments %} -

No comments so far.

- {% endif %} -
-{% endmacro %} - {% macro render_comment(comment, editform) %} -
+
{{ editform.csrf_token }} {{ editform.id() }}
-

{{ comment.user.username or "Deleted account" }}

+

{{ comment.user.username or "Deleted account" }}

{% if current_user.is_moderator %} {% if not comment.deleted %} diff --git a/yadc/templates/layout/settings.html b/yadc/templates/layout/settings.html index f3ce5f8..3be2d56 100644 --- a/yadc/templates/layout/settings.html +++ b/yadc/templates/layout/settings.html @@ -3,7 +3,7 @@ {% block sidebar %}
Profile settings - {% if current_user.is_author or current_user.is_moderator -%} + {% if current_user.is_uploader or current_user.is_moderator -%} Post management {%- endif %} {% if current_user.is_moderator -%} diff --git a/yadc/templates/user/profile.html b/yadc/templates/user/profile.html index 87616b0..67ed4a7 100644 --- a/yadc/templates/user/profile.html +++ b/yadc/templates/user/profile.html @@ -1,4 +1,5 @@ {% extends 'layout/base.html' %} +{% from '_includes.html' import render_comment with context %} {#{% block sidebar %} {{ super()}} @@ -6,29 +7,53 @@ {% endblock %}#} {% block content %} - + {% if not comments %} +

No comments so far.

+ {% endif %} +
+ {% endblock %} \ No newline at end of file