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("/@