diff --git a/files/assets/css/TheMotte.css b/files/assets/css/TheMotte.css index a3a0dd05d..d024b6d07 100644 --- a/files/assets/css/TheMotte.css +++ b/files/assets/css/TheMotte.css @@ -3,8 +3,13 @@ :root { --primary: #1a6187; - --bright: #2384b8; - --very-bright: #78c0e6; + + --primary-dark1: #165476; + --primary-dark2: #134662; + + --primary-light1: #2280B3; + --primary-light2: #2F9CD7; + --dark: #c7c7c7; --secondary: #c7c7c7; --gray: #c7c7c7; @@ -31,16 +36,16 @@ a { color: var(--primary); } .btn-primary { color: var(--primary); } -.btn-primary:hover { color: var(--bright); } +.btn-primary:hover { color: var(--primary-light1); } .btn-secondary { color: var(--primary); } -.btn-secondary:hover { color: var(--bright); } +.btn-secondary:hover { color: var(--primary-light1); } .btn-success { color: var(--primary); } -.btn-success:hover { color: var(--bright); } +.btn-success:hover { color: var(--primary-light1); } .btn-danger { color: var(--primary); } -.btn-danger:hover { color: var(--bright); } +.btn-danger:hover { color: var(--primary-light1); } .btn-primary.disabled, .btn-primary:disabled, .btn-secondary.disabled, .btn-secondary:disabled, @@ -49,9 +54,19 @@ a { color: var(--primary); } color: var(--muted); } +.comment-write .comment-format .format { + color: var(--primary); +} +.comment-write .comment-format .format:hover { + color: var(--primary-light1); +} +.format .fa-bold:hover, .format .fa-italic:hover, .format .fa-quote-right:hover, .format .fa-link:hover, .format .fa-image:hover { + color: var(--primary-light1); +} + .custom-control-input:checked ~ .custom-control-label::before { opacity: 1; - background-color: var(--very-bright) !important; + background-color: var(--primary-light2) !important; border: var(--primary) solid 0.1px; } @@ -65,7 +80,7 @@ a { color: var(--primary); } } .form-control:focus { - border-color: var(--bright) !important; + border-color: var(--primary-light1) !important; } .btn { @@ -105,17 +120,76 @@ pre { blockquote { color: var(--gray-400); } - +#account-menu { + left: -6px; +} +#main-navigation { + max-width: 2000px; + margin-left: auto; + margin-right: auto; +} #profilestuff > * { color: var(--gray-400) !important; } - +#profilestuff a { + color: var(--primary-light2) !important; +} +#profilestuff h1 { + color: var(--primary-light1) !important; +} +div.deleted { + background-color: var(--gray-400) !important; +} +div.deleted.banned { + background-color: var(--gray) !important; +} +.comment-body > .comment-anchor { + padding: 10px; +} .comment-anchor:target, .unread { background: #00000055 !important; } - -#frontpage .post-title a:visited, .visited { - color: #7a7a7a !important; +#frontpage .posts .card, #userpage .posts .card, #search .posts .card { + border: none; +} +#search .post-info, +#userpage .post-info, +#frontpage .post-info { + display:flex; +} +#search .post-actions, +#userpage .post-actions, +#frontpage .post-actions { + margin-left:auto; +} +#search .post-actions .list-inline, +#userpage .post-actions .list-inline, +#frontpage .post-actions .list-inline { + align-items: center; + height:100%; +} +#search .post-title a:hover, +#userpage .post-title a:hover, +#frontpage .post-title a:hover { + text-decoration: underline; +} +a::not(.visited), +#frontpage .post-title a:not(:visited), +#userpage .post-title a:not(:visited), +#search .post-title a:not(:visited) { + color: var(--primary-light1); +} +a.visited, +#frontpage .post-title a:visited, +#userpage .post-title a:visited, +#search .post-title a:visited { + color: var(--primary-dark1); +} +.comment .comment-collapse-desktop { + border-left: 2px solid var(--primary-dark1) !important; +} +.comment .comment-collapse-desktop:hover { + border-left: 2px solid var(--primary-light2) !important; } .usernote-link { diff --git a/files/assets/css/main.css b/files/assets/css/main.css index aa14ec392..16d4ae2e6 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -283,7 +283,7 @@ mark, .mark { } code { font-size: 87.5%; - color: #e83e8c; + color: var(--primary-dark1); word-wrap: break-word; } a > code { @@ -584,7 +584,7 @@ a.btn.disabled, fieldset:disabled a.btn { border-color: var(--primary); } .btn-primary:hover { - color: var; + color: #fff; background-color: var(--primary); border-color: #0062cc; } @@ -2151,9 +2151,18 @@ a.bg-light:hover, a.bg-light:focus, button.bg-light:hover, button.bg-light:focus } .shadow-sm { box-shadow: 0 0.1px 3px 0 rgba(0, 0, 0, 0.05), 0 0.1px 2px 0 rgba(0, 0, 0, 0.03) !important; + -webkit-box-shadow: 0 0.1px 3px 0 rgba(0, 0, 0, 0.05), 0 0.1px 2px 0 rgba(0, 0, 0, 0.03) !important; + -moz-box-shadow: 0 0.1px 3px 0 rgba(0, 0, 0, 0.05), 0 0.1px 2px 0 rgba(0, 0, 0, 0.03) !important; +} +.shadow-lg { + box-shadow: -20px 20px 28px -20px rgba(0,0,0,0.51); + -webkit-box-shadow: -20px 20px 28px -20px rgba(0,0,0,0.51); + -moz-box-shadow: -20px 20px 28px -20px rgba(0,0,0,0.51); } .shadow { box-shadow: 0 0.1px 3px rgba(190, 113, 113, 0.05), 0 0 0 0.1px rgba(0, 0, 0, 0.05) !important; + -webkit-box-shadow: 0 0.1px 3px rgba(190, 113, 113, 0.05), 0 0 0 0.1px rgba(0, 0, 0, 0.05) !important; + -moz-box-shadow: 0 0.1px 3px rgba(190, 113, 113, 0.05), 0 0 0 0.1px rgba(0, 0, 0, 0.05) !important; } .shadow-none { box-shadow: none !important; diff --git a/files/assets/images/TheMotte/default_text.webp b/files/assets/images/TheMotte/default_text.webp index 56529d1c7..c56703697 100644 Binary files a/files/assets/images/TheMotte/default_text.webp and b/files/assets/images/TheMotte/default_text.webp differ diff --git a/files/assets/images/default_thumb_link.webp b/files/assets/images/default_thumb_link.webp index b24586a50..ad1b0a9c5 100644 Binary files a/files/assets/images/default_thumb_link.webp and b/files/assets/images/default_thumb_link.webp differ diff --git a/files/assets/js/comments_v.js b/files/assets/js/comments_v.js index 284a67d25..afeede7a5 100644 --- a/files/assets/js/comments_v.js +++ b/files/assets/js/comments_v.js @@ -243,6 +243,11 @@ function post_comment(fullname){ commentForm=document.getElementById('comment-form-space-'+fullname); commentForm.innerHTML = data["comment"].replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, ''); bs_trigger(commentForm); + + let placeholder = document.getElementById("placeholder-comment"); + if(placeholder){ + placeholder.parentNode.removeChild(placeholder); + } } else { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; diff --git a/files/assets/js/marked.custom.js b/files/assets/js/marked.custom.js index 172ae9cba..970bebcd0 100644 --- a/files/assets/js/marked.custom.js +++ b/files/assets/js/marked.custom.js @@ -1,214 +1,55 @@ -function appendToken(parentElement, childToken) { - var childElement = tokenToHTMLElement(childToken); - if (typeof childElement === 'string') { - parentElement.textContent += childElement; - } else if (childElement !== null) { - parentElement.appendChild(childElement) - } -} -function appentTextOrElement(parentElement, textOrElement) { - if (typeof textOrElement === 'string') { - parentElement.textContent += textOrElement; - } else { - parentElement.appendChild(textOrElement); - } -} - -function motteSpecialMarkdown(text) { - if (typeof text !== 'string') { - return ''; - } - - var spoilerMatch = text.match(/^(.*?)\|\|(.*?)\|\|(.*)$/); - - if (spoilerMatch) { - var left = spoilerMatch[1]; - var mid = spoilerMatch[2]; - var right = spoilerMatch[3]; - var parentSpan = document.createElement('span'); - var leftSpan = document.createElement('span'); - var spoilerSpan = document.createElement('span'); - var rightSpan = document.createElement('span'); - spoilerSpan.textContent = mid; - spoilerSpan.classList.add('spoiler'); - appentTextOrElement(leftSpan, motteSpecialMarkdown(left)); - appentTextOrElement(rightSpan, motteSpecialMarkdown(right)); - parentSpan.appendChild(leftSpan); - parentSpan.appendChild(spoilerSpan); - parentSpan.appendChild(rightSpan); - return parentSpan; - } else { - return text; - } -} - -function tokenToHTMLElement(token) { - var element = null; - - if (token.type === 'space') { - element = document.createElement('span'); - element.textContent = ' '; - return element; - } else if (typeof token.type === 'undefined' || token.type === 'text') { - element = document.createElement('span'); - appentTextOrElement(element, motteSpecialMarkdown(token.text)); - return element; - } else if (token.type === 'hr') { - return document.createElement('hr'); - } else if (token.type === 'br') { - return document.createElement('br'); - } else if (token.type === 'heading') { - element = document.createElement('h' + Math.floor(Math.max(1, Math.min(6, token.depth)))); - } else if (token.type === 'code') { - element = document.createElement('pre'); - element.setAttribute('data-lang', token.lang); - } else if (token.type === 'list_item') { - element = document.createElement('li'); - } else if (token.type === 'blockquote') { - element = document.createElement('blockquote'); - } else if (token.type === 'list') { - if (token.ordered) { - element = document.createElement('ol'); - } else { - element = document.createElement('ul'); - } - } else if (token.type === 'table') { - var table, thead, tbody, tr, th, td; - table = document.createElement('table'); - table.classList.add('table'); - thead = document.createElement('thead'); - tbody = document.createElement('thead'); - tr = document.createElement('tr'); - for (var x = 0; x < token.header.length; x++) { - th = document.createElement('th'); - appendToken(th, token.header[x]); - tr.appendChild(th); - } - thead.appendChild(tr); - table.appendChild(thead); - for (var y = 0; y < token.rows.length; y++) { - row = token.rows[y]; - tr = document.createElement('tr'); - for (var x = 0; x < row.length; x++) { - td = document.createElement('td'); - appendToken(td, row[x]); - tr.appendChild(td); +marked.use({ + extensions: [ + { + name: 'spoiler', + level: 'block', + start: function(src){ + const match = src.match(/\|\|/); + return match != null ? match.index : -1; + }, + tokenizer: function(src) { + const rule = /^\|\|([\s\S]*?)\|\|/; + const match = rule.exec(src); + if(match){ + const token = { // Token to generate + type: 'spoiler', // Should match "name" above + raw: match[0], // Text to consume from the source + text: match[0].trim(), // Additional custom properties + tokens: [] // Array where child inline tokens will be generated + }; + this.lexer.inline( + token.text.slice(2,-2), + token.tokens + ); + return token; + } + }, + renderer(token) { + const content = this.parser.parseInline(token.tokens); + return `${content}`; } - tbody.appendChild(tr); } - table.appendChild(tbody); - return table; - } else if (token.type === 'paragraph') { - element = document.createElement('p'); - } else if (token.type === 'div') { - element = document.createElement('div'); - } else if (token.type === 'em') { - element = document.createElement('i'); - } else if (token.type === 'strong') { - element = document.createElement('b'); - } else if (token.type === 'del') { - element = document.createElement('del'); - } else if (token.type === 'codespan') { - element = document.createElement('code'); - element.textContent = token.text; - return element; - } else if (token.type === 'escape') { - } else if (token.type === 'link') { - element = document.createElement('a'); - element.setAttribute('href', token.href); - element.textContent = token.text; - return element; - } else if (token.type === 'image') { - element = document.createElement('img'); - element.setAttribute('src', token.href); - element.setAttribute('alt', token.text); - return element; - } else { - console.log(token); - element = document.createElement('div'); - } - - var children = (token.tokens || token.items || []); - if (element !== null && children.length > 0) { - for (var i = 0; i < children.length; i++) { - var childElement = tokenToHTMLElement(children[i]); - if (childElement.outerHTML.match(/"spoiler"/g)) { - console.log(element, token, childElement, children[i]); - } - appendToken(element, children[i]); - } - } else if (element.children.length === 0 && element.textContent === '') { - element.textContent += token.text; - } - - return element; -} - -function safeMarkdown(input) { - // var seenTokens = []; - // var outputToken = {"type": "div", "raw": input, "text": "", "tokens": []}; - // function seeRecursive(token) { - // seenTokens.push(token); - // var children = ( - // token.tokens - // || token.items - // || (token.header||[]).concat(token.rows||[]) - // || [] - // ); - // if (token.header) { - // children = children.concat(token.header); - // } - // for (var y = 0; y < (token.rows||[]).length; y++) { - // children = children.concat(token.rows[y]); - // } - // for (var i = 0; i < children.length; i++) { - // seeRecursive(children[i]); - // } - // } - // marked.use({ - // walkTokens: function(token) { - // if (!seenTokens.includes(token)) { - // outputToken.tokens.push(token); - // seeRecursive(token); - // } - // }, - // }); - // marked(input); - // marked.use({ - // walkTokens: false, - // tokenizer: false, - // }); - - // [ 'escape', 'del', ]; - - // return tokenToHTMLElement(outputToken); - - const html = marked.parse(input); - return DOMPurify.sanitize(html); -} - -setTimeout(() => markdown('post-text','preview'), 200); + ] +}); function markdown(first, second) { - var input = document.getElementById(first).value; - + var input = document.getElementById(first); var dest = document.getElementById(second); - for (var i = 0; i < dest.children.length; i++) { - dest.removeChild(dest.children[i]); + if(dest && input && input.value.trim() !== ''){ + for (var i = 0; i < dest.children.length; i++) { + dest.removeChild(dest.children[i]); + } + const html = marked.parse(input.value); + dest.innerHTML = DOMPurify.sanitize(html); } - document.getElementById(second).innerHTML = safeMarkdown(input); } -function charLimit(form, text) { - - var input = document.getElementById(form); - - var text = document.getElementById(text); - - var length = input.value.length; - - var maxLength = input.getAttribute("maxlength"); +function charLimit(form, content) { + let input = document.getElementById(form); + let text = document.getElementById(content); + let length = input.value.length; + let maxLength = input.getAttribute("maxlength"); if (length >= maxLength) { text.style.color = "#E53E3E"; @@ -219,6 +60,7 @@ function charLimit(form, text) { else { text.style.color = "#A0AEC0"; } - text.innerText = length + ' / ' + maxLength; } + +setTimeout(() => markdown('post-text','preview'), 200); \ No newline at end of file diff --git a/files/routes/front.py b/files/routes/front.py index 4d9612cf0..1f7d620c5 100644 --- a/files/routes/front.py +++ b/files/routes/front.py @@ -392,8 +392,6 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, ccmode="false" @app.get("/changelog") @auth_required def changelog(v): - - try: page = max(int(request.values.get("page", 1)), 1) except: page = 1 diff --git a/files/routes/static.py b/files/routes/static.py index f174e50c5..65227250e 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -287,10 +287,14 @@ def contact(v): @auth_required def submit_contact(v): body = request.values.get("message") + email = request.values.get("email") if not body: abort(400) + if not email: email = None - body = f'This message has been sent automatically to all admins via [/contact](/contact)\n\nMessage:\n\n' + body - body_html = sanitize(body) + header = "This message has been sent automatically to all admins via [/contact](/contact)\n" + email = f"Email: {email}\n" + message = f"Message:\n{body}\n\n" + html = sanitize(f"{header}\n{email}\n{message}") if request.files.get("file") and request.headers.get("cf-ipcountry") != "T1": file=request.files["file"] @@ -298,7 +302,7 @@ def submit_contact(v): name = f'/images/{time.time()}'.replace('.','') + '.webp' file.save(name) url = process_image(name) - body_html += f'' + html += f'' elif file.content_type.startswith('video/'): file.save("video.mp4") with open("video.mp4", 'rb') as f: @@ -310,15 +314,13 @@ def submit_contact(v): if error == 'File exceeds max duration': error += ' (60 seconds)' return {"error": error}, 400 if url.endswith('.'): url += 'mp4' - body_html += f"

{url}

" + html += f"

{url}

" else: return {"error": "Image/Video files only"}, 400 - - new_comment = Comment(author_id=v.id, parent_submission=None, level=1, - body_html=body_html, + body_html=html, sentto=2 ) g.db.add(new_comment) diff --git a/files/routes/users.py b/files/routes/users.py index f9e8e28d2..f592a7d69 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -275,7 +275,7 @@ def upvoters(v, username): pos = (pos+1, users[pos][1]) except: pos = (len(users)+1, 0) - return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Up', name2=f'@{username} biggest simps') + return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Up', name2=f'Who upvotes @{username}') @@ -301,7 +301,7 @@ def downvoters(v, username): pos = (pos+1, users[pos][1]) except: pos = (len(users)+1, 0) - return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Down', name2=f'@{username} biggest haters') + return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Down', name2=f'Who downvotes @{username}') @app.get("/@/upvoting") @auth_required @@ -325,7 +325,7 @@ def upvoting(v, username): pos = (pos+1, users[pos][1]) except: pos = (len(users)+1, 0) - return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Up', name2=f'Who @{username} simps for') + return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Up', name2=f'Who @{username} upvotes') @app.get("/@/downvoting") @auth_required @@ -349,7 +349,7 @@ def downvoting(v, username): pos = (pos+1, users[pos][1]) except: pos = (len(users)+1, 0) - return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Down', name2=f'Who @{username} hates') + return render_template("voters.html", v=v, users=users[:25], pos=pos, name='Down', name2=f'Who @{username} downvotes') diff --git a/files/templates/comments.html b/files/templates/comments.html index e3e610f75..f1228ea72 100644 --- a/files/templates/comments.html +++ b/files/templates/comments.html @@ -61,7 +61,7 @@ {% if (c.is_banned or c.deleted_utc or c.is_blocking) and not (v and v.admin_level > 1) and not (v and v.id==c.author_id) %}
- +
@@ -158,7 +158,7 @@
{% if not isreply %} - + {% endif %}
@@ -202,7 +202,7 @@ {% if not c.author %} {{c.print()}} {% endif %} - {{c.author_name}} + {{c.author_name}} {% if v and v.admin_level > 2 %}   - - -