1
1
Fork 0

Forms. Styles. Scripts. Managements. BRUH.

dev
Jan Kužílek 5 years ago
parent 16123a078e
commit 50beeb9bdf

@ -50,13 +50,17 @@ def create_app():
def utility_processor(): def utility_processor():
return dict(utils=utils) return dict(utils=utils)
with app.app_context():
assets.append_path(os.path.join(app.root_path, 'assets'))
# print(assets.load_path)
#assets.url = app.static_url_path #assets.url = app.static_url_path
scss = AssetsBundle( scss = AssetsBundle(
'default.scss', 'main.scss',
filters=['libsass','cssmin'], output='all.css') depends=('*.scss'), filters=['libsass','cssmin'], output='all.css')
assets.register('scss_all', scss) assets.register('scss_all', scss)
js = AssetsBundle( js = AssetsBundle(
'base.js', 'management.js', 'formswitchers.js', 'base.js',
'search.js', 'search.js',
# filters='rjsmin', # filters='rjsmin',
output='all.js') output='all.js')

@ -0,0 +1,256 @@
.flash_msgs {
display: flex;
flex-flow: column-reverse nowrap;
position: fixed;
z-index: 20;
// top: 0;
//left: 0;
bottom: 0;
right: 0;
margin: 0;
// margin-top: 20px;
padding: 10px;
//max-width: 1300;
font-size: .9em;
pointer-events: none;
> li {
//width: 300px;
//margin: 0 auto;
width: 250px;
padding: 10px;
&:not(:first-child) {
margin-bottom: 10px;
}
background-color: $notif-bg-color;
overflow: hidden;
@keyframes fade {
0%,100% { opacity: 0 }
20%,80% { opacity: 1 }
}
opacity: 0;
animation: fade 7s normal;
}
}
h3 {
margin: 0;
margin-bottom: 1em;
font-size: 1.3em;
}
h4 {
margin: 0;
margin-bottom: .8em;
}
.comment-form {
margin-left: 10px;
max-width: 500px;
input:required {
box-shadow: none;
}
textarea {
width: 100%;
background: #444a;
border: none;
color: inherit;
font: inherit;
}
}
.editingable {
&:not(.time-to-edit){
.edit {
display: none;
}
}
&.time-to-edit {
.notedit {
display: none;
}
}
}
input[type=text], textarea {
resize: vertical;
width: 100%;
&.edit, .edit & {
background: #444a;
border: none;
color: inherit;
font: inherit;
}
}
form .tag_input, .tag_input form {
.tag-suggester {
width: calc(100% - 50px);
position: relative;
// input[type=text] {
// width: 100%;
// }
> .tag_suggest_dropdown {
display: flex;
flex-flow: column nowrap;
align-items: start;
// width: 100%;
top: 100%;
left: 0;
position: absolute;
z-index: 10;
overflow: auto;
background-color: #2d2d2de0;
}
}
.tag-container {
display: flex;
> a {
margin: 2px 2px;
// padding: .4em .75em;
padding: .35em .6em;
//text-align: center;
border-radius: 4px;
background-color: #121212ff;
cursor: pointer;
> * { pointer-events: none; }
> .fa-tag {
font-size: .9em;
margin-right: 2px;
}
> .count {
// display: none;
font-size: .8em;
}
&:not(:hover) {
> span.close {
display: none;
}
> span.plus {
display: none;
}
}
&:hover {
> span.count {
display: none;
}
}
&.tagselected {
background-color: #400808ff;
}
&.tag_hide {
display: none;
}
}
}
}
form {
// margin: 0 auto;
// width: 300px;
//text-align: center;
// padding: 5px;
// input[type=text] {
// @extend .fb-input;
// margin: 0;
// // background: none;
// // border: none;
// // color: inherit;
// // font: inherit;
// //line-height: 2em;
// // padding: 2px 6px;
// }
// input[type=submit] {
// @extend .fb-input;
// // padding: 0;
// width: unset;
// margin: .2rem;
// }
// select {
// @extend .fb-select;
// -moz-appearance: none;
// -webkit-appearance: none;
// margin: 0;
// // width: 100%;
// }
// input[type=file] {
// @extend .fb-input;
// padding: 0;
// background: none;
// border: none;
// color: inherit;
// width: unset;
// }
input {
margin: 5px 0;
//font-size: 1em;
&:not([type=checkbox]):not([type=submit]):not([type=radio]):not([type=file]) {
// width: 100%;
}
// &[type=file] {
// //display: none;
// @extend .fb-input;
// padding: 0;
// background: none;
// border: none;
// }
// &[type=text] {
// @extend .fb-input;
// // margin: 0;
// // background: none;
// // border: none;
// // color: inherit;
// // font: inherit;
// //line-height: 2em;
// // padding: 2px 6px;
// }
// &[type=submit] {
// @extend .fb-input;
// // padding: 0;
// width: unset;
// margin: .2rem;
// }
}
// select {
// @extend .fb-select;
// -moz-appearance: none;
// -webkit-appearance: none;
// margin: 0;
// // width: 100%;
// }
}

@ -0,0 +1,230 @@
.main-wrap {
$bp-desktop: ">=desktop";
$bp-tablet: "<desktop";
margin: 0 auto;
max-width: 1300px;
$main-wrap-padding: 8px;
padding: $main-wrap-padding;
padding-top: 0;
padding-bottom: 0;
// $sidepanel-width: 14rem;
$sidepanel-width: 18rem;
.important-subwrap {
display: flex;
@include media($bp-tablet) {
flex-flow: column nowrap;
}
@include media($bp-desktop) {
flex-flow: row nowrap;
}
overflow: visible; // for negative margin of .post-single
> section.sidepanel {
flex-shrink: 0;
@include media($bp-desktop) {
// width: 14em;
width: $sidepanel-width;
height: 0; // for overflow
}
padding: 10px;
article {
margin-bottom: 10px;
}
article.tags {
@include media($bp-tablet) {
.tag-container {
flex-flow: row wrap;
}
}
@include media($bp-desktop) {
.tag-container {
flex-flow: column nowrap;
align-items: start;
}
}
}
article.post-desc {
display: flex;
flex-flow: column nowrap;
font-size: .9em;
> img {
display: block;
max-width: 128px;
}
}
}
> section:not(.sidepanel) {
// fucking just for desktop because son of a bitch negative margin does shit when in mobile layout
// it's a hack and I know it
// pls, destiny, have a mercy
@include media($bp-desktop) {
width: 100%;
}
}
}
section.post-list {
overflow: hidden;
@include media("<tablet") {
margin-left: -#{$main-wrap-padding};
margin-right: -#{$main-wrap-padding};
}
.posts {
display: flex;
flex-flow: row wrap;
$figure-margin: 8px;
@include media($bp-tablet) {
margin-left: -#{$figure-margin};
margin-right: -#{$figure-margin};
}
&::after {
content: "";
flex: 10000/*350*/ 0 350px;
}
> figure {
position: relative;
margin: $figure-margin;
img {
display: block;
width: 100%;
height: 100%;
// border-radius: 4px;
transition: .2s ease;
}
&:hover img {
opacity: .7;
}
}
}
}
section.post-single {
@include media($bp-desktop) {
padding: 8px;
}
@include media($bp-tablet) {
order: -1;
margin-bottom: $main-wrap-padding;
}
@include media("<tablet") {
// margin-top: -$main-wrap-padding;
margin-left: -#{$main-wrap-padding};
margin-right: -#{$main-wrap-padding};
}
img {
display: block;
max-width: 100%;
}
}
section.comments {
padding: 10px;
@include media($bp-desktop) {
margin-left: $sidepanel-width;
}
> .comment-container {
padding: 0 10px;
max-width: 500px;
article.comment {
overflow: hidden;
margin-bottom: 1em;
p, textarea {
// margin-top: .5em;
margin: 0;
// margin-bottom: 1em;
&.deleted {
color: red;
}
}
.comment-head {
display: flex;
justify-content: space-between;
}
}
}
}
section.management-table {
table {
margin: 0 auto;
// border-collapse: collapse
}
tr {
background-color: #303030;
th, td {
padding: 6px 10px;
}
th {
background-color: #606060;
}
// input[type=submit]:not([name=create]) {
label > input {
display: none;
}
.fa {
padding: 4px 4px;
align-self: center;
font-size: 1.5em;
cursor: pointer;
}
}
}
.pagin {
margin: 10px 0;
// @include media($bp-desktop) {
// margin-right: calc(#{$sidepanel-width}*3/4);
// }
display: flex;
flex-flow: row nowrap;
justify-content: center;
> a {
display: block;
background-color: #0005;
padding: 8px 12px;
margin: 0 2px;
}
}
}
footer { // DUE TO OVERFLOW OF THE SIDE PANEL, TRY TO KEEP IT ON THE RIGHT
padding: 10px;
// background-color: $header-bg-color;
text-align: center;
}

@ -0,0 +1,31 @@
function switchEdit(el) {
if (!el.classList.contains('time-to-edit')) {
el.classList.add('time-to-edit')
} else {
el.classList.remove('time-to-edit')
}
}
function commentSwitcher() {
let comments = document.querySelectorAll('section.comments article.comment')
comments.forEach(comment => comment
.querySelectorAll('.comment-head .control-edit')
.forEach(el => el
.addEventListener('click', ev => switchEdit(comment.querySelector('.editingable')))
)
)
// comment.target.closest('form.editingable')
}
function mgmtSwitcher() {
let rows = document.querySelectorAll("section.management-table tbody > tr")
rows.forEach(row => row
.querySelectorAll('label.to-edit, label.to-close')
.forEach(el => el
.addEventListener('click', ev => switchEdit(row))
)
)
}
commentSwitcher()
mgmtSwitcher()

@ -0,0 +1,160 @@
$header-bg-color: #222;
$nav-bg-color: #111d;//#20141fd0;
$nav-bg-color_hover: #333;//#20141fa0;
header {
display: flex;
align-items: baseline;
padding: 0 10px;
background-color: $header-bg-color;
> a.logo {
font-size: 2em;
margin: 6px;
}
// @include mobile { font-size: 1.3em; }
// @include desktop { font-size: 1.1em; }
@include media("<tablet") { position: relative; }
> nav {
flex-grow: 1;
display: flex;
> ._overlay {
display: none;
}
@include media("<tablet") {
display: none;
&._drop {
display: flex;
flex-flow: column nowrap;
position: absolute;
margin: 0;
top: 100%;
left: 0;
right: 0;
z-index: 10;
background-color: $nav-bg-color;
}
> a, a#user-menu, .user_dropdown > a {
padding: 12px;
padding-left: 24px;
//text-align: center;
&:hover, &:active {
background-color: $nav-bg-color_hover;
}
}
.user {
&::before {
content: "";
display: block;
border-top: 1px solid grey;
margin: 2px 12px;
}
#user-menu {
display: block;
}
.user_dropdown {
display: flex;
flex-flow: column nowrap;
}
}
> ._overlay {
display: block;
position: fixed;
width: 100%;
height: 100%;
z-index: -1;
background-color: #0006;
@at-root {
html.oh { overflow: hidden; }
}
}
}
@include media(">=tablet") {
margin: 0px 5px;
align-items: center;
> * {
margin: 0 5px;
padding: 6px 0;
}
> .user {
padding: 0;
margin-left: auto;
margin-right: 0;
#user-menu {
display: block;
padding: 6px 10px; //replication of nav/*
}
position: relative;
.user_dropdown {
display: none;
// opacity: .1; // BOI DAT HACK
// height: 0;
// width: 0;
// overflow: hidden;
a {
padding: 10px;
}
a:hover {
background-color: $nav-bg-color_hover;
}
}
&:hover > .user_dropdown {
display: flex;
flex-flow: column nowrap;
position: absolute;
margin: 0;
top: 100%;
// left: 0;
right: 0;
z-index: 10;
background-color: $nav-bg-color;
// opacity: 1; // BOI DAT HACK
// height: unset;
// width: unset;
// transition: .2s ease;
}
}
}
}
> #nav-menu {
display: none;
@include media("<tablet") {
display: block;
margin: 5px;
margin-left: auto;
padding: 0 2px;
align-self: center;
font-size: 2em;
cursor: pointer;
}
}
}

@ -0,0 +1,37 @@
@import "_include-media";
$breakpoints: (tablet: 560px, desktop: 900px);
$bg-color: #222; //#20141f;
$text-color: #fff;
$a-color: #bbb;
$ahover-color: #909090;
//$notif-bg-color: #542772d0;
$notif-bg-color: #000c;
@import "base-types";
@import "header";
@import "default";
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Verdana, Geneva, Tahoma, sans-serif;
// font-family: monospace; font-size: 1.1em;
//font-size: 14px;
background-color: $bg-color;
color: $text-color;
}
a {
color: $a-color;
text-decoration: none;
}
a:hover {
color: $ahover-color;
text-decoration: none;
}

@ -23,7 +23,7 @@ def manage_users(page):
op_level=user.op_level.name, op_level=user.op_level.name,
user_status=user.user_status.name) user_status=user.user_status.name)
return render_template('manage/users.html', users=users, createform=UserForm()) return render_template('manage/users.html', users=users, elements=users.items, createform=UserForm())
@bp.route('/posts', defaults={'page': 1}) @bp.route('/posts', defaults={'page': 1})
@bp.route('/posts/<int:page>') @bp.route('/posts/<int:page>')
@ -41,7 +41,7 @@ def manage_posts(page):
status=post.status.name, status=post.status.name,
source=post.source) source=post.source)
return render_template('manage/posts.html', posts=posts) return render_template('manage/posts.html', posts=posts, elements=posts.items)
@bp.route('/tags', defaults={'page': 1}) @bp.route('/tags', defaults={'page': 1})
@bp.route('/tags/<int:page>') @bp.route('/tags/<int:page>')
@ -56,7 +56,7 @@ def manage_tags(page):
content=tag.content_deser, content=tag.content_deser,
category=tag.category.name) category=tag.category.name)
return render_template('manage/tags.html', tags=tags, createform=TagForm()) return render_template('manage/tags.html', tags=tags, elements=tags.items, createform=TagForm())
@ -182,7 +182,7 @@ def modify_comment():
# flash(str(request.form)) # flash(str(request.form))
if form.validate(): if form.validate():
if form.create.data: if form.create.data:
el = Comment(content=form.content.data, post_id=form.post_id.data, user=current_user) el = Comment(content=form.content.data.strip(), post_id=form.post_id.data, user=current_user)
db.session.add(el) db.session.add(el)
db.session.commit() db.session.commit()
@ -198,7 +198,7 @@ def modify_comment():
db.session.commit() db.session.commit()
flash('{} deleted.'.format(str(el))) flash('{} deleted.'.format(str(el)))
elif form.edit.data: elif form.edit.data:
if form.content.data: el.content = form.content.data if form.content.data: el.content = form.content.data.strip()
db.session.commit() db.session.commit()
flash('Changes to {} have been applied.'.format(str(el))) flash('Changes to {} have been applied.'.format(str(el)))

File diff suppressed because one or more lines are too long

@ -0,0 +1,238 @@
function switchEdit(el) {
if (!el.classList.contains('time-to-edit')) {
el.classList.add('time-to-edit')
} else {
el.classList.remove('time-to-edit')
}
}
function commentSwitcher() {
let comments = document.querySelectorAll('section.comments article.comment')
comments.forEach(comment => comment
.querySelectorAll('.comment-head .control-edit')
.forEach(el => el
.addEventListener('click', ev => switchEdit(comment.querySelector('.editingable')))
)
)
// comment.target.closest('form.editingable')
}
function mgmtSwitcher() {
let rows = document.querySelectorAll("section.management-table tbody > tr")
rows.forEach(row => row
.querySelectorAll('label.to-edit, label.to-close')
.forEach(el => el
.addEventListener('click', ev => switchEdit(row))
)
)
}
commentSwitcher()
mgmtSwitcher()
let nav_menu = document.querySelectorAll("#nav-menu, nav#main-nav > ._overlay")
function nav_menu_event(event) {
let drop = document.getElementById("main-nav")
let html = document.getElementsByTagName('html')[0]
if (!drop.classList.contains("_drop")) {
drop.classList.add("_drop")
html.classList.add("oh")
window.scrollTo(0, 0);
} else {
drop.classList.remove("_drop")
html.classList.remove("oh")
}
}
nav_menu.forEach(element => {
element.addEventListener('click', nav_menu_event)
});
document.getElementById("user-menu").addEventListener('click', (ev) => {
let drop = document.getElementsByClassName("user_dropdown")[0]
if (!drop.classList.contains("_drop")) {
drop.classList.add("_drop")
} else {
drop.classList.remove("_drop")
}
})
let tagroot = document.querySelector('.tag_input')
let sel_tags = tagroot.querySelector('div.tags_selected')
let predef_tags = tagroot.querySelector('div.tags_inpage') // Should be optional
let suggestroot = tagroot.querySelector('.tag_suggester')
suggestroot.insertAdjacentHTML("beforeend", `<input type="hidden" name="${suggestroot.dataset.inputname}">`)
let suggest_hidden = suggestroot.querySelector(`input[name=${suggestroot.dataset.inputname}][type=hidden]`)
let suggest_input = suggestroot.querySelector(`input[name=${suggestroot.dataset.inputname}][type=text]`)
suggest_input.removeAttribute('name')
if (suggest_input.hasAttribute('required')) {
suggest_input.removeAttribute('required')
suggest_hidden.setAttribute('required', '')
}
// suggest_input.value = ''
suggest_input.removeAttribute('value')
let tag_suggest_dropdown = suggestroot.querySelector('.tag_suggest_dropdown')
// 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) {
let tag = document.createElement("a")
tag.classList.add("tagselected")
tag.dataset.tagname = tagname
tag.insertAdjacentHTML("beforeend", `
<span class="fa fa-tag"></span>
<span class="name"></span>
<span class="fa fa-close close"></span>
`)
tag.querySelector("span.name").textContent = tagname.replace(/_/g, ' ')
// tag.querySelector("input[type=hidden]").setAttribute('name', `tag#${tagname}`)
return tag
}
function form_addtag(tagname) {
let val = suggest_hidden.value.split(' ')
val.push(tagname)
suggest_hidden.value = val.join(' ').trim()
}
function form_removetag(tagname) {
let val = suggest_hidden.value.split(' ')
val.splice(val.indexOf(tagname), 1)
suggest_hidden.value = val.join(' ').trim()
}
function add_selected(tagname) {
if (predef_tags) {
let pagetag = predef_tags.querySelector(`a[data-tagname=${tagname}]`)
if (pagetag) {
pagetag.classList.add('tag_hide')
}
}
let newtag = create_selection_tag(tagname)
newtag.addEventListener('click', (event) => {
remove_selected(event.target.dataset.tagname)
// console.log(`Deselected: ${event.target.dataset.tagname}`)
})
sel_tags.appendChild(newtag)
form_addtag(tagname)
}
function remove_selected(tagname) {
if (predef_tags) {
let pagetag = predef_tags.querySelector(`a[data-tagname=${tagname}]`)
if (pagetag) {
pagetag.classList.remove('tag_hide')
}
}
sel_tags.querySelector(`a[data-tagname=${tagname}]`).remove()
form_removetag(tagname)
}
// Page tags click to select
if (predef_tags) {
predef_tags.querySelectorAll("a").forEach(element => {
element.addEventListener('click', (event) => {
add_selected(event.target.dataset.tagname)
event.preventDefault()
})
})
}
// Generate selected by url query
let query = getJsonFromUrl()
if (query['tags']) {
query['tags'].split('+').forEach((tag) => {
add_selected(tag)
})
}
// Suggestions
function create_suggestion_tag(tagname) {
let tag = document.createElement("a")
tag.classList.add("tagsuggestion")
tag.dataset.tagname = tagname
tag.insertAdjacentHTML("beforeend", `
<span class="fa fa-tag"></span>
<span class="name"></span>
<span class="fa fa-plus plus"></span>
`)
tag.querySelector("span.name").textContent = tagname.replace(/_/g, ' ')
return tag
}
function render_suggestions(data) {
tag_suggest_dropdown.innerHTML = ''
let tagnames = Array.from(sel_tags.querySelectorAll('a')).map(a => a.dataset.tagname)
let i = 0
data.forEach((el) => {
if (i > 5) return
if (tagnames.includes(el.content)) return
let sugtag = create_suggestion_tag(el.content)
sugtag.addEventListener('click', (event) => {
add_selected(event.target.dataset.tagname)
suggest_input.value = ''
render_suggestions([])
event.preventDefault()
})
tag_suggest_dropdown.appendChild(sugtag)
i++
});
}
// Ajax suggestion handler
var ajax_timeout
suggest_input.addEventListener('input', (event) => {
clearTimeout(ajax_timeout)
let value = suggest_input.value.replace(/ /g, '_').trim()
if (value.length < 2) {
render_suggestions([])
return
}
ajax_timeout = setTimeout(() => {
fetch('/post/tags?q='+value).then((response) => {
console.log(response)
return response.json()
}).then((data) => {
// fill suggestions
// console.log(data)
render_suggestions(data)
})
}, 500)
})
// search_input.addEventListener('keypress', (event) => {
// if (event.keyCode == 13) {
// // event.preventDefault()
// }
// })
// search_input.addEventListener('blur', (event) => {
// if (event.explicitOriginalTarget != null) {
// classlist = event.explicitOriginalTarget.parentNode.classList
// if (classlist.contains('tags_selected') || classlist.contains('tags_inpage') || classlist.contains('search_dropdown')) {
// setTimeout(() => search_input.focus(), 2)
// }
// }
// console.log(event)
// })
// page_tags.querySelectorAll('a').forEach((el) => el.removeAttribute('href'))

@ -1,17 +0,0 @@
let comment_container = document.querySelector('section.comments .comment_container')
let comments = comment_container.querySelectorAll('.comment')
function triggerEdit(comment) {
let form = comment.querySelector('form.editingable')
if (!form.classList.contains('time-to-edit')) {
form.classList.add('time-to-edit')
} else {
form.classList.remove('time-to-edit')
}
}
comments.forEach((comment) => {
// comment.querySelector('p.comment_content').addEventListener('dblclick', (event) => triggerEdit(comment))
comment.querySelector('.comment_head .control_edit').addEventListener('click', (event) => triggerEdit(comment))
})

@ -1,720 +0,0 @@
@import "_include-media";
// @import "include-media/dist/_include-media";
$breakpoints: (tablet: 560px, desktop: 900px);
// $formbase__prefix: "fb-";
// $formbase__padding: .2rem;
// @import "formbase/src/styles/main";
// @import "boilerform/assets/scss/boilerform";
* {
box-sizing: border-box;
}
$bg-color: #222; //#20141f;
$text-color: #fff;
$a-color: #bbb;
$ahover-color: #909090;
$header-bg-color: #222;
$nav-bg-color: #111d;//#20141fd0;
$nav-bg-color_hover: #333;//#20141fa0;
//$notif-bg-color: #542772d0;
$notif-bg-color: #000c;
body {
margin: 0;
font-family: Verdana, Geneva, Tahoma, sans-serif;
// font-family: monospace; font-size: 1.1em;
//font-size: 14px;
background-color: $bg-color;
color: $text-color;
}
a {
color: $a-color;
text-decoration: none;
}
a:hover {
color: $ahover-color;
text-decoration: none;
}
header {
display: flex;
align-items: baseline;
padding: 0 10px;
background-color: $header-bg-color;
> a.logo {
font-size: 2em;
margin: 6px;
}
// @include mobile { font-size: 1.3em; }
// @include desktop { font-size: 1.1em; }
@include media("<tablet") { position: relative; }
> nav {
flex-grow: 1;
display: flex;
> ._overlay {
display: none;
}
@include media("<tablet") {
display: none;
&._drop {
display: flex;
flex-flow: column nowrap;
position: absolute;
margin: 0;
top: 100%;
left: 0;
right: 0;
z-index: 10;
background-color: $nav-bg-color;
}
> a, a#user-menu, .user_dropdown > a {
padding: 12px;
padding-left: 24px;
//text-align: center;
&:hover, &:active {
background-color: $nav-bg-color_hover;
}
}
.user {
&::before {
content: "";
display: block;
border-top: 1px solid grey;
margin: 2px 12px;
}
#user-menu {
display: block;
}
.user_dropdown {
display: flex;
flex-flow: column nowrap;
}
}
> ._overlay {
display: block;
position: fixed;
width: 100%;
height: 100%;
z-index: -1;
background-color: #0006;
@at-root {
html.oh { overflow: hidden; }
}
}
}
@include media(">=tablet") {
margin: 0px 5px;
align-items: center;
> * {
margin: 0 5px;
padding: 6px 0;
}
> .user {
padding: 0;
margin-left: auto;
margin-right: 0;
#user-menu {
display: block;
padding: 6px 10px; //replication of nav/*
}
position: relative;
.user_dropdown {
display: none;
// opacity: .1; // BOI DAT HACK
// height: 0;
// width: 0;
// overflow: hidden;
a {
padding: 10px;
}
a:hover {
background-color: $nav-bg-color_hover;
}
}
&:hover > .user_dropdown {
display: flex;
flex-flow: column nowrap;
position: absolute;
margin: 0;
top: 100%;
// left: 0;
right: 0;
z-index: 10;
background-color: $nav-bg-color;
// opacity: 1; // BOI DAT HACK
// height: unset;
// width: unset;
// transition: .2s ease;
}
}
}
}
> #nav-menu {
display: none;
@include media("<tablet") {
display: block;
margin: 5px;
margin-left: auto;
padding: 0 2px;
align-self: center;
font-size: 2em;
cursor: pointer;
}
}
}
.flash_msgs {
display: flex;
flex-flow: column-reverse nowrap;
position: fixed;
z-index: 20;
// top: 0;
//left: 0;
bottom: 0;
right: 0;
margin: 0;
// margin-top: 20px;
padding: 10px;
//max-width: 1300;
font-size: .9em;
pointer-events: none;
> li {
//width: 300px;
//margin: 0 auto;
width: 250px;
padding: 10px;
&:not(:first-child) {
margin-bottom: 10px;
}
background-color: $notif-bg-color;
overflow: hidden;
@keyframes fade {
0%,100% { opacity: 0 }
20%,80% { opacity: 1 }
}
opacity: 0;
animation: fade 7s normal;
}
}
.main_wrap {
$bp-desktop: ">=desktop";
$bp-tablet: "<desktop";
margin: 0 auto;
max-width: 1300px;
$main-wrap-padding: 8px;
padding: $main-wrap-padding;
padding-top: 0;
padding-bottom: 0;
h3 {
margin: 0;
margin-bottom: 10px;
font-size: 1.3em;
}
form .tag_input, .tag_input form {
.tag_suggester {
width: calc(100% - 50px);
position: relative;
// input[type=text] {
// width: 100%;
// }
> .tag_suggest_dropdown {
display: flex;
flex-flow: column nowrap;
align-items: start;
// width: 100%;
top: 100%;
left: 0;
position: absolute;
z-index: 10;
overflow: auto;
background-color: #2d2d2de0;
}
}
.tag_container {
display: flex;
> a {
margin: 2px 2px;
// padding: .4em .75em;
padding: .35em .6em;
//text-align: center;
border-radius: 4px;
background-color: #121212ff;
cursor: pointer;
> * { pointer-events: none; }
> .fa-tag {
font-size: .9em;
margin-right: 2px;
}
> .count {
// display: none;
font-size: .8em;
}
&:not(:hover) {
> span.close {
display: none;
}
> span.plus {
display: none;
}
}
&:hover {
> span.count {
display: none;
}
}
&.tagselected {
background-color: #400808ff;
}
&.tag_hide {
display: none;
}
}
}
}
// $side-panel-width: 14rem;
$side-panel-width: 18rem;
.important_subwrap {
display: flex;
@include media($bp-tablet) {
flex-flow: column nowrap;
}
@include media($bp-desktop) {
flex-flow: row nowrap;
}
overflow: visible; // for negative margin of .post_single
> section.side_panel {
flex-shrink: 0;
@include media($bp-desktop) {
// width: 14em;
width: $side-panel-width;
height: 0; // for overflow
}
padding: 10px;
article {
// &:not(:last-child) {
// margin-bottom: 10px;
// }
margin-bottom: 10px;
}
article.tags {
@include media($bp-tablet) {
.tag_container {
flex-flow: row wrap;
}
}
@include media($bp-desktop) {
.tag_container {
flex-flow: column nowrap;
align-items: start;
}
}
}
article.post_desc {
display: flex;
flex-flow: column nowrap;
font-size: .9em;
> img {
display: block;
max-width: 128px;
}
}
}
> section:not(.side_panel) {
// fucking just for desktop because son of a bitch negative margin does shit when in mobile layout
// it's a hack and I know it
// pls, destiny, have a mercy
@include media($bp-desktop) {
width: 100%;
}
}
}
section.post_list {
overflow: hidden;
@include media("<tablet") {
margin-left: -#{$main-wrap-padding};
margin-right: -#{$main-wrap-padding};
}
.posts {
display: flex;
flex-flow: row wrap;
$figure-margin: 8px;
@include media($bp-tablet) {
margin-left: -#{$figure-margin};
margin-right: -#{$figure-margin};
}
&::after {
content: "";
flex: 10000/*350*/ 0 350px;
}
> figure {
position: relative;
margin: $figure-margin;
img {
display: block;
width: 100%;
height: 100%;
// border-radius: 4px;
transition: .2s ease;
}
&:hover img {
opacity: .7;
}
}
}
}
section.post_single {
@include media($bp-desktop) {
padding: 8px;
}
@include media($bp-tablet) {
order: -1;
margin-bottom: $main-wrap-padding;
}
@include media("<tablet") {
// margin-top: -$main-wrap-padding;
margin-left: -#{$main-wrap-padding};
margin-right: -#{$main-wrap-padding};
}
img {
display: block;
max-width: 100%;
}
}
section.comments {
padding: 10px;
@include media($bp-desktop) {
margin-left: $side-panel-width;
}
> .comment_container {
padding: 0 10px;
max-width: 500px;
article.comment {
overflow: hidden;
margin-bottom: 1em;
}
h4 {
// margin-top: .5em;
margin: 0;
margin-bottom: .5em;
}
p, textarea {
// margin-top: .5em;
margin: 0;
// margin-bottom: 1em;
&.deleted {
color: red;
}
}
.comment_head {
display: flex;
justify-content: space-between;
}
}
> .form > form {
margin-left: 10px;
max-width: 500px;
input:required {
box-shadow: none;
}
textarea {
width: 100%;
background: #444a;
border: none;
color: inherit;
font: inherit;
}
}
}
section.management_table {
table {
margin: 0 auto;
// border-collapse: collapse
}
tr {
// &:nth-child(even), th {
// background-color: #404040;
// }
th {
background-color: #606060;
}
// &:nth-child(even) {
background-color: #303030;
// }
th, td {
padding: 6px 10px;
}
input {
}
&:not(.edit) {
td > .edit {
display: none;
}
}
&.edit {
td > .show {
display: none;
}
}
input[type=submit]:not([name=create]) {
display: none;
}
.fa {
padding: 4px 4px;
align-self: center;
font-size: 1.5em;
cursor: pointer;
}
}
}
form.editingable {
&:not(.time-to-edit){
.edit {
display: none;
}
}
&.time-to-edit {
.notedit {
display: none;
}
}
input[type=text], textarea {
resize: vertical;
width: 100%;
&.edit, .edit & {
background: #444a;
border: none;
color: inherit;
font: inherit;
}
}
}
form {
// margin: 0 auto;
// width: 300px;
//text-align: center;
// padding: 5px;
// input[type=text] {
// @extend .fb-input;
// margin: 0;
// // background: none;
// // border: none;
// // color: inherit;
// // font: inherit;
// //line-height: 2em;
// // padding: 2px 6px;
// }
// input[type=submit] {
// @extend .fb-input;
// // padding: 0;
// width: unset;
// margin: .2rem;
// }
// select {
// @extend .fb-select;
// -moz-appearance: none;
// -webkit-appearance: none;
// margin: 0;
// // width: 100%;
// }
// input[type=file] {
// @extend .fb-input;
// padding: 0;
// background: none;
// border: none;
// color: inherit;
// width: unset;
// }
input {
margin: 5px 0;
//font-size: 1em;
&:not([type=checkbox]):not([type=submit]):not([type=radio]):not([type=file]) {
// width: 100%;
}
// &[type=file] {
// //display: none;
// @extend .fb-input;
// padding: 0;
// background: none;
// border: none;
// }
// &[type=text] {
// @extend .fb-input;
// // margin: 0;
// // background: none;
// // border: none;
// // color: inherit;
// // font: inherit;
// //line-height: 2em;
// // padding: 2px 6px;
// }
// &[type=submit] {
// @extend .fb-input;
// // padding: 0;
// width: unset;
// margin: .2rem;
// }
}
// select {
// @extend .fb-select;
// -moz-appearance: none;
// -webkit-appearance: none;
// margin: 0;
// // width: 100%;
// }
}
.pagin {
margin: 10px 0;
// @include media($bp-desktop) {
// margin-right: calc(#{$side-panel-width}*3/4);
// }
display: flex;
flex-flow: row nowrap;
justify-content: center;
> a {
display: block;
background-color: #0005;
padding: 8px 12px;
margin: 0 2px;
}
}
}
footer { // DUE TO OVERFLOW OF THE SIDE PANEL, TRY TO KEEP IT ON THE RIGHT
padding: 10px;
// background-color: $header-bg-color;
text-align: center;
}

@ -1,17 +0,0 @@
let rows = document.querySelectorAll("section.management_table tbody > tr")
function show_edit_controls(event) {
let row = event.target.closest("tr")
console.log(row)
if (!row.classList.contains("edit")) {
row.classList.add("edit")
} else {
row.classList.remove("edit")
}
}
rows.forEach(element => {
element.querySelectorAll("label.to-edit, label.to-close").forEach(el => {
el.addEventListener('click', show_edit_controls)
})
});

@ -8,12 +8,24 @@
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
<!-- DEPRECATED + wrong function name, but whatever -->
{% macro management_gen_line(field, formfield) %} {% macro management_gen_line(field, formfield) %}
<span class="show">{{ field }}</span> <span class="show">{{ field }}</span>
<span class="edit">{{ formfield() }}</span> <span class="edit">{{ formfield() }}</span>
{{ errors(formfield) }} {{ errors(formfield) }}
{% endmacro %} {% endmacro %}
{% macro management_row_gen(field_formfield) %} <!-- COPY OF genfield IN management.html -->
{% macro genfield(formfield=None) %}
{% if not formfield %}
<td>
<span>{{ caller() }}</span>
</td>
{% else %}
<td>
<span class="notedit">{{ caller() }}</span>
<span class="edit">{{ formfield() }}</span>
{{ errors(formfield) }}
</td>
{% endif %}
{% endmacro %} {% endmacro %}

@ -28,6 +28,7 @@
</article> </article>
{% endmacro %} --> {% endmacro %} -->
<!-- DEPRECATED! -->
{% macro render_comments() %} {% macro render_comments() %}
<div class="comment_container"> <div class="comment_container">
{% for comment in comments %} {% for comment in comments %}
@ -51,6 +52,7 @@
</div> </div>
{% endmacro %} {% endmacro %}
<!-- DEPRECATED! -->
{% macro render_post_edit() %} {% macro render_post_edit() %}
<article class="edit"> <article class="edit">
<h3>Edit</h3> <h3>Edit</h3>
@ -58,6 +60,7 @@
</article> </article>
{% endmacro %} {% endmacro %}
<!-- DEPRECATED? -->
{% macro render_sidenav(sidenav_links) %} {% macro render_sidenav(sidenav_links) %}
<article class="sidenav"> <article class="sidenav">
{% for class, (name, link) in sidenav_links.items() %} {% for class, (name, link) in sidenav_links.items() %}
@ -77,3 +80,70 @@
<div class="tag_container tags_selected"></div> <div class="tag_container tags_selected"></div>
</div> </div>
{% endmacro %} {% endmacro %}
<!-- EFFECTIVELY DEPRECATED NOW (AS OF management.html) -->
{% from "_formhelpers.html" import errors %}
{% macro render_management_table(elements) %}
<table>
<thead>
<tr>
{% for heading in elements[0][1].keys() %}
<th>{{ heading }}</th>
{% endfor %}
<th>Manage</th>
</tr>
</thead>
<tbody>
{% for element,fields in elements %}
<tr>
<form class="editingable" action="{{ url_for('manage.modify_tag') }}" method="post">
{{ element.editform.csrf_token }}
{{ element.editform.id() }}
{% for field,formfield in fields.values() %}
{% if not formfield %}
<td>
<span>{{ field }}</span>
</td>
{% else %}
<td>
<span class="notedit">{{ field }}</span>
<span class="edit">{{ formfield() }}</span>
{{ errors(formfield) }}
</td>
{% endif %}
{% endfor %}
<td>
<label class="notedit to-edit">
<span class="fa fa-edit"></span>
</label>
<label class="edit to-close">
<span class="fa fa-close"></span>
</label>
<label class="edit">
<span class="fa fa-check"></span>
{{ element.editform.edit() }}
</label>
<label>
<span class="fa fa-trash-o"></span>
{{ element.editform.delete() }}
</label>
</td>
</form>
</tr>
{% endfor %}
{{ caller() }}
{#<!-- <tr>
<form action="{{ url_for('manage.modify_tag') }}" method="post">
{{ createform.csrf_token }}
<td>{{ createform.content() }}</td>
<td>{{ createform.category() }}</td>
<td>{{ createform.create() }}</td>
</form>
</tr> -->#}
</tbody>
</table>
{% endmacro %}

@ -53,14 +53,18 @@
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<div class="main_wrap"> <div class="main-wrap">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
<footer> <footer>
Produced by KuxaBeast Produced by KuxaBeast
</footer> </footer>
<script src="{{ url_for('static', filename="base.js") }}"></script>
<script src="{{ url_for('static', filename="management.js") }}"></script> {% assets "js_all" %}
<script src="{{ ASSET_URL }}"></script>
{% endassets %}
{#<script src="{{ url_for('static', filename="base.js") }}"></script>
<script src="{{ url_for('static', filename="management.js") }}"></script>#}
</body> </body>
</html> </html>

@ -1,8 +1,8 @@
{% extends 'layout/base.html' %} {% extends 'layout/base.html' %}
{% block content %} {% block content %}
<div class="important_subwrap"> <div class="important-subwrap">
<section class="side_panel"> <section class="sidepanel">
{% block sidebar %}{% endblock %} {% block sidebar %}{% endblock %}
</section> </section>
{% block main_content %}{% endblock %} {% block main_content %}{% endblock %}

@ -1,37 +1,41 @@
{% extends 'layout/base_sidebar.html' %} {% extends 'layout/base_sidebar.html' %}
{% block sidebar %} {% block sidebar %}
<article class="rating">
<h3>Rating</h3>
<div class="rating-input">
{% for rating in ('safe', 'questionable', 'explicit') %}
<input type="radio" name="rating" id="rating-{{ rating }}" value="{{ rating }}" {% if rating == session.get('index_settings', {}).get('rating', 'safe') %}checked{% endif %} onclick="submit()">
<label for="rating-{{ rating }}">{{ rating.capitalize() }}</label>
<br>
{% endfor %}
</div>
</article>
<article class="tags tag_input"> <article class="tags tag_input">
<form action="{% block search_endpoint %}{{ url_for('post.posts') }}{% endblock %}" method="get"> <h3>Search</h3>
<h3>Search</h3> <div class="tag-input">
<div class="tag_suggester" data-inputname="tags"> <form action="{% block search_endpoint %}{{ url_for('post.posts') }}{% endblock %}" method="get">
<input type="text" name="tags" autocomplete="off" value="{{ request.args.get('tags', '') }}"> <div class="tag-suggester" data-inputname="tags">
<div class="tag_container tag_suggest_dropdown"></div> <input type="text" name="tags" autocomplete="off" value="{{ request.args.get('tags', '') }}">
</div> <div class="tag-container tag_suggest_dropdown"></div>
<input type="submit" value="Search"> </div>
<!-- <input type="submit" value="Search"> -->
<div class="rating">
{% for rating in ('safe', 'questionable', 'explicit') %}
<input type="radio" name="rating" id="rating-{{ rating }}" value="{{ rating }}" {% if rating == session.get('index_settings', {}).get('rating', 'safe') %}checked{% endif %} onclick="submit()">
<label for="rating-{{ rating }}">{{ rating.capitalize() }}</label>
<br>
{% endfor %}
</div>
<h3>Tags</h3> <!-- <h3>Tags</h3> -->
<div class="tag_container tags_selected"></div> <div class="tag-container tags-selected"></div>
<div class="tag_container tags_inpage"> <div class="tag-container tags-inpage">
{% for tag in tags %} {% for tag in tags %}
<a class="taginpage" data-tagname="{{ tag.content }}" href="{{ tag.endpoint }}"> <a class="taginpage" data-tagname="{{ tag.content }}" href="{{ tag.endpoint }}">
<span class="fa fa-tag"></span> <span class="fa fa-tag"></span>
<span class="name">{{ tag.content_deser }}</span> <span class="name">{{ tag.content_deser }}</span>
<span class="count">{{ tag.count }}</span> <span class="count">{{ tag.count }}</span>
<span class="fa fa-plus plus"></span> <span class="fa fa-plus plus"></span>
<!-- <span class="post_ids">{{ tag.post_ids }}</span> --> <!-- <span class="post_ids">{{ tag.post_ids }}</span> -->
</a> </a>
{% endfor %} {% endfor %}
</div> </div>
</form> </form>
</div>
<script src="{{ url_for('static', filename="search.js") }}"></script> <script src="{{ url_for('static', filename="search.js") }}"></script>
</article> </article>
{% endblock %} {% endblock %}

@ -0,0 +1,60 @@
{% extends 'layout/settings.html' %}
{% block main_content %}{{ self.management_table() }}{% endblock %}
{% block management_table %}
<table>
<thead>
<tr>
{% block field_headings %}{% endblock %}
<th>Manage</th>
</tr>
</thead>
<tbody>
{% for element in elements %}
<tr class="editingable">
<form action="{{ url_for('manage.modify_tag') }}" method="post">
{{ element.editform.csrf_token }}
{{ element.editform.id() }}
{% block fields scoped %}{% endblock %}
<td>
<label class="notedit to-edit">
<span class="fa fa-edit"></span>
</label>
<label class="edit to-close">
<span class="fa fa-close"></span>
</label>
<label class="edit">
<span class="fa fa-check"></span>
{{ element.editform.edit() }}
</label>
<label>
<span class="fa fa-trash-o"></span>
{{ element.editform.delete() }}
</label>
</td>
</form>
</tr>
{% endfor %}
{% block createform %}{% endblock %}
</tbody>
</table>
{% endblock %}
{% from "_formhelpers.html" import errors %}
{% macro genfield(formfield=None) %}
{% if not formfield %}
<td>
<span>{{ caller() }}</span>
</td>
{% else %}
<td>
<span class="notedit">{{ caller() }}</span>
<span class="edit">{{ formfield() }}</span>
{{ errors(formfield) }}
</td>
{% endif %}
{% endmacro %}

@ -1,42 +1,40 @@
{% extends 'layout/settings.html' %} {% extends 'layout/management.html' %}
{% from '_includes.html' import render_pagination with context %} {% from '_includes.html' import render_pagination with context %}
{% from "_formhelpers.html" import management_gen_line, errors %}
{% block main_content %} {% block main_content %}
<section class="management_table manage_posts"> <section class="management-table manage-posts">
<table> {{ super() }}
<thead>
<tr>
<th>ID</th>
<th>MD5</th>
<th>Rating</th>
<th>Status</th>
<th>Source</th>
<th>Manage</th>
</tr>
</thead>
<tbody>
{% for post in posts.items %}
<form action="{{ url_for('manage.modify_post') }}" method="post">
{{ post.editform.csrf_token }}
{{ post.editform.id() }}
<tr>
<td>{{ post.id }}</td>
<td><pre style="margin: 0;">{{ post.md5[:7] }}</pre></td>
<td>{{ management_gen_line(post.rating.name.capitalize(), post.editform.rating) }}</td>
<td>{{ management_gen_line(post.status.name.capitalize(), post.editform.status) }}</td>
<td>{{ management_gen_line(post.source, post.editform.source) }}</td>
<td>
<label class="show to-edit"><span class="fa fa-edit"></span></label>
<label class="edit to-close"><span class="fa fa-close"></span></label>
<label class="edit"><span class="fa fa-check"></span>{{ post.editform.edit() }}</label>
<label><span class="fa fa-trash-o"></span>{{ post.editform.delete() }}</label>
</td>
</tr>
</form>
{% endfor %}
</tbody>
</table>
{{ render_pagination('manage.manage_posts', posts) }} {{ render_pagination('manage.manage_posts', posts) }}
</section> </section>
{% endblock %} {% endblock %}
{% block field_headings %}
<th>ID</th>
<th>MD5</th>
<th>Rating</th>
<th>Status</th>
<th>Source</th>
{% endblock %}
{% block fields %}
{% call genfield() %}
{{ element.id }}
{% endcall %}
{% call genfield() %}
<pre style="margin: 0;">{{ element.md5[:7] }}</pre>
{% endcall %}
{% call genfield(element.editform.rating) %}
{{ element.rating.name.capitalize() }}
{% endcall %}
{% call genfield(element.editform.status) %}
{{ element.status.name.capitalize() }}
{% endcall %}
{% call genfield(element.editform.source) %}
{{ element.source }}
{% endcall %}
{% endblock %}

@ -1,47 +1,36 @@
{% extends 'layout/settings.html' %} {% extends 'layout/management.html' %}
{% from '_includes.html' import render_pagination with context %} {% from '_includes.html' import render_pagination with context %}
{% from "_formhelpers.html" import management_gen_line, errors %}
{% block main_content %} {% block main_content %}
<section class="management_table manage_posts"> <section class="management-table manage-tags">
<table> {{ super() }}
<thead>
<tr>
<!-- <th>ID</th> -->
<th>Content</th>
<th>Category</th>
<th>Manage</th>
</tr>
</thead>
<tbody>
{% for tag in tags.items %}
<form action="{{ url_for('manage.modify_tag') }}" method="post">
{{ tag.editform.csrf_token }}
{{ tag.editform.id() }}
<tr>
<!-- <td>{{ tag.id }}</td> -->
<td>{{ tag.content_deser }}</td>
<td>{{ management_gen_line(tag.category.name.capitalize(), tag.editform.category) }}</td>
<td>
<label class="show to-edit"><span class="fa fa-edit"></span></label>
<label class="edit to-close"><span class="fa fa-close"></span></label>
<label class="edit"><span class="fa fa-check"></span>{{ tag.editform.edit() }}</label>
<label><span class="fa fa-trash-o"></span>{{ tag.editform.delete() }}</label>
</td>
</tr>
</form>
{% endfor %}
<form action="{{ url_for('manage.modify_tag') }}" method="post">
{{ createform.csrf_token }}
<tr>
<!-- <td></td> -->
<td>{{ createform.content() }}</td>
<td>{{ createform.category() }}</td>
<td>{{ createform.create() }}</td>
</tr>
</form>
</tbody>
</table>
{{ render_pagination('manage.manage_tags', tags) }} {{ render_pagination('manage.manage_tags', tags) }}
</section> </section>
{% endblock %} {% endblock %}
{% block field_headings %}
<th>Content</th>
<th>Category</th>
{% endblock %}
{% block fields %}
{% call genfield() %}
{{ element.content_deser }}
{% endcall %}
{% call genfield(element.editform.category) %}
{{ element.category.name.capitalize() }}
{% endcall %}
{% endblock %}
{% block createform %}
<tr>
<form action="{{ url_for('manage.modify_tag') }}" method="post">
{{ createform.csrf_token }}
<td>{{ createform.content() }}</td>
<td>{{ createform.category() }}</td>
<td>{{ createform.create() }}</td>
</form>
</tr>
{% endblock %}

@ -1,56 +1,55 @@
{% extends 'layout/settings.html' %} {% extends 'layout/management.html' %}
{% from '_includes.html' import render_pagination with context %} {% from '_includes.html' import render_pagination with context %}
{% from "_formhelpers.html" import management_gen_line, errors %}
{% block main_content %} {% block main_content %}
<section class="management_table manage_users"> <section class="management-table manage-users">
<table> {{ super() }}
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>User status</th>
<th>Perm level</th>
<th>Last login</th>
<th>Manage</th>
</tr>
</thead>
<tbody>
{% for user in users.items %}
<form action="{{ url_for('manage.modify_user') }}" method="post">
{{ user.editform.csrf_token }}
{{ user.editform.id() }}
<tr>
<td>{{ user.id }}</td>
<td>{{ management_gen_line(user.username, user.editform.username) }}</td>
<td>{{ management_gen_line(user.user_status.name.capitalize(), user.editform.user_status) }}</td>
<td>{{ management_gen_line(user.op_level.name.capitalize(), user.editform.op_level) }}</td>
<td>{{ user.last_login.strftime('%I:%M %p %d %b, %Y') if user.last_login else 'Not yet logged in' }}</td>
<td>
<label class="show to-edit"><span class="fa fa-edit"></span></label>
<label class="edit to-close"><span class="fa fa-close"></span></label>
<label class="edit"><span class="fa fa-check"></span>{{ user.editform.edit() }}</label>
<label><span class="fa fa-trash-o"></span>{{ user.editform.delete(
onclick="return confirm('Do you really want to delete this user?')"
)}}</label>
</td>
</tr>
</form>
{% endfor %}
{#<!-- <form action="{{ url_for('manage.modify_user') }}" method="post">
{{ createform.csrf_token }}
{{ createform.id() }}
<tr>
<td></td>
<td>{{ createform.username() }}</td>
<td>{{ createform.user_status() }}</td>
<td>{{ createform.op_level() }}</td>
<td></td>
<td>{{ createform.create() }}</td>
</tr>
</form> -->#}
</tbody>
</table>
{{ render_pagination('manage.manage_users', users) }} {{ render_pagination('manage.manage_users', users) }}
</section> </section>
{% endblock %} {% endblock %}
{% block field_headings %}
<th>ID</th>
<th>Username</th>
<th>User status</th>
<th>Perm level</th>
<th>Last login</th>
{% endblock %}
{% block fields %}
{% call genfield() %}
{{ element.id }}
{% endcall %}
{% call genfield(element.editform.username) %}
{{ element.username }}
{% endcall %}
{% call genfield(element.editform.user_status) %}
{{ element.user_status.name.capitalize() }}
{% endcall %}
{% call genfield(element.editform.op_level) %}
{{ element.op_level.name.capitalize() }}
{% endcall %}
{% call genfield() %}
{{ element.last_login.strftime('%I:%M %p %d %b, %Y') if element.last_login else 'Not yet logged in' }}
{% endcall %}
{% endblock %}
{#{% block createform %}
<tr>
<form action="{{ url_for('manage.modify_user') }}" method="post">
{{ createform.csrf_token }}
{{ createform.id() }}
<td></td>
<td>{{ createform.username() }}</td>
<td>{{ createform.user_status() }}</td>
<td>{{ createform.op_level() }}</td>
<td></td>
<td>{{ createform.create() }}</td>
</form>
</tr>
{% endblock %}#}

@ -4,7 +4,7 @@
{% block search_endpoint %}{% endblock %} {% block search_endpoint %}{% endblock %}
{% block main_content %} {% block main_content %}
<section class="post_list"> <section class="post-list">
<div class="posts"> <div class="posts">
{% for post in posts.items %} {% for post in posts.items %}
<figure style="{{ post.flex }}"> <figure style="{{ post.flex }}">

@ -3,56 +3,57 @@
{% from "_formhelpers.html" import errors %} {% from "_formhelpers.html" import errors %}
{% block sidebar %} {% block sidebar %}
<article class="post_desc"> <article class="post-desc">
<!-- <h4>Description</h4> --> <!-- <h4>Description</h4> -->
<!-- <img src="/static/profile.jpg" alt=""> --> <!-- <img src="/static/profile.jpg" alt=""> -->
<div class="id">Id: {{ post.id }}</div> <div class="id">Id: {{ post.id }}</div>
<div class="author">Author: {{ post.author.username or "Deleted Account" }}</div> <div class="author">Author: {{ post.author.username or "Deleted Account" }}</div>
{% if post.is_approved %} {% if post.is_approved %}
<div class="approver">Approved by: {{ post.approver.username }}</div> <div class="approver">Approved by: {{ post.approver.username }}</div>
{% endif %} {% endif %}
{% if not post.is_approved %} {% if not post.is_approved %}
<div class="status">Status: {{ post.status.name.capitalize() }}</div> <div class="status">Status: {{ post.status.name.capitalize() }}</div>
{% endif %} {% endif %}
<div class="time">Posted: {{ post.natural_created() }}</div> <div class="time">Posted: {{ post.natural_created() }}</div>
<div class="source">Source: <a href="{{ post.source }}">{{ post.source }}</a></div> <div class="source">Source: <a href="{{ post.source }}">{{ post.source }}</a></div>
<div class="size">File size: {{ post.filesize_human }}</div> <div class="size">File size: {{ post.filesize_human }}</div>
<div class="resolution">Image res: {{ post.image_resolution }}</div> <div class="resolution">Image res: {{ post.image_resolution }}</div>
<div class="jpeg"><a href="{{ post.url(path=post.file_uri, endpoint='jpeg') }}">Enlarge image</a></div> <div class="jpeg"><a href="{{ post.url(path=post.file_uri, endpoint='jpeg') }}">Enlarge image</a></div>
{% if post.filetype.name == 'png' %} {% if post.filetype.name == 'png' %}
<div class="png"><a href="{{ post.url(path=post.file_uri) }}">Original PNG file</a></div> <div class="png"><a href="{{ post.url(path=post.file_uri) }}">Original PNG file</a></div>
{% endif %} {% endif %}
</article> </article>
{{ super() }} {{ super() }}
{% if post.can_edit %} {% if post.can_edit %}
<article class="edit"> <article class="post-edit">
<h3>Edit</h3> <h3>Edit</h3>
<div class="post-editform">
<form action="{{ url_for('post.editpost') }}" method="post"> <form action="{{ url_for('post.editpost') }}" method="post">
{{ editform.csrf_token }} {{ editform.csrf_token }}
{{ editform.id() }} {{ editform.id() }}
<div>
{{ render_tag_input(editform.tags) }} {{ render_tag_input(editform.tags) }}
{{ errors(editform.tags) }} {{ errors(editform.tags) }}
</div>
<div> {{ editform.source }}
{{ editform.source }} {{ errors(editform.source) }}
</div>
<div> {{ editform.edit() }}
{{ editform.edit() }}
</div>
</form> </form>
</article> </div>
{% endif %} </article>
{% endif %}
{% endblock %} {% endblock %}
{% block main_content %} {% block main_content %}
<section class="post_single"> <section class="post-single">
<div class="image"> <div class="image">
<img src="{{ post.url(path=post.file_uri, endpoint='jpeg') }}" alt=""> <img src="{{ post.url(path=post.file_uri, endpoint='jpeg') }}" alt="">
</div> </div>
@ -63,34 +64,35 @@
{{ super() }} {{ super() }}
<section class="comments"> <section class="comments">
<h3>Comments</h3> <h3>Comments</h3>
<div class="comment_container"> <div class="comment-container">
{% for comment in comments %} {% for comment in comments %}
<article class="comment"> <article class="comment">
<div class="comment_head"> <form class="editingable" action="{{ url_for('post.comment') }}" method="post">
<h4>{{ comment.user.username or "Deleted account" }}</h4> <div class="comment-head">
{% if comment.can_edit %} <h4>{{ comment.user.username or "Deleted account" }}</h4>
<span class="controls"> <span class="controls">
<span class="control_edit">edit</span> {% if comment.can_edit %}
</span> <span class="control-edit">edit</span>
{% endif %} {% endif %}
</div> </span>
</div>
{% if not comment.deleted %}
<div class="comment-editform">
<form class="comment_editform editingable" action="{{ url_for('post.comment') }}" method="post"> {{ comment.editform.csrf_token }}
{{ comment.editform.csrf_token }} {{ comment.editform.id() }}
{{ comment.editform.id() }}
<p class="comment_content notedit">{{ comment.content }}</p> {% if not comment.deleted %}
<p class="comment-content notedit">{{ comment.content }}</p>
{{ comment.editform.content(class="edit") }} {{ comment.editform.content(class="edit") }}
{{ comment.editform.edit(class="edit") }} {% else %}
{{ comment.editform.delete(class="edit") }} <p class="deleted notedit">{{ comment.delete_reason }}</p>
{#<!-- {{ comment.editform.delete_reason(class="edit") }} -->#}
{% endif %}
{{ comment.editform.edit(class="edit") }}
{{ comment.editform.delete(class="edit") }}
</div>
</form> </form>
{% else %}
<p class="deleted">{{ comment.delete_reason }}</p>
{% endif %}
</article> </article>
{% endfor %} {% endfor %}
@ -98,19 +100,20 @@
<p>No comments so far.</p> <p>No comments so far.</p>
{% endif %} {% endif %}
</div> </div>
<script src="{{ url_for('static', filename="comment.js") }}"></script> {#<script src="{{ url_for('static', filename="comment.js") }}"></script>#}
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
<div class="form">
<h3>Reply</h3> <h3>Reply</h3>
<div class="comment-form">
<form action="{{ url_for('post.comment') }}" method="post"> <form action="{{ url_for('post.comment') }}" method="post">
{{ comment_form.csrf_token }} {{ comment_form.csrf_token }}
{{ comment_form.post_id() }} {{ comment_form.post_id() }}
<div>
{{ comment_form.content() }} {{ comment_form.content() }}
{{ errors(comment_form.content) }} {{ errors(comment_form.content) }}
</div>
<div>{{ comment_form.create() }}</div> {{ comment_form.create() }}
</form> </form>
</div> </div>
{% else %} {% else %}

Loading…
Cancel
Save