master
Aevann1 2021-08-22 19:00:07 +02:00
parent b2c7a14bd9
commit 8aee250116
10 changed files with 1910 additions and 1910 deletions

View File

@ -124,4 +124,4 @@
</body>
</html
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,150 +1,150 @@
{% extends "default.html" %}
{% block title %}
<title>{{'SITE_NAME' | app_config}} - Formatting</title>
<meta name="description" content="{{'SITE_NAME' | app_config}} Formatting">
{% endblock %}
{% block content %}
<pre>
</pre>
{% filter markdown %}
# Formatting
On {{'SITE_NAME' | app_config}}, you can use Markdown formatting.
## Inline formatting
{% endfilter %}
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Type</th>
<th>Displays as</th>
</tr>
</thead>
<tr>
<td>Italics</td>
<td>*text*</td>
<td><i>text</i></td>
</tr>
<tr>
<td>Bold</td>
<td>**text**</td>
<td><b>text</b></td>
</tr>
<tr>
<td>Code</td>
<td>`text`</td>
<td><code>text</code></td>
</tr>
<tr>
<td>Strikethrough</td>
<td>~~text~~</td>
<td><del>text</del></td>
</tr>
<tr>
<td>Links</td>
<td>[{{'SITE_NAME' | app_config}}]({{request.host_url}})</td>
<td><a href="{{request.host_url}}">{{'SITE_NAME' | app_config}}</a></td>
</tr>
<tr>
<td>Emojis</td>
<td>:marseylove:</td>
<td><img data-toggle="tooltip" title="marseylove" delay="0" height="20" src="/assets/images/emojis/marseylove.gif"></td>
</tr>
</table>
{% filter markdown %}
## Block formatting
These Markdown tags format an entire paragraph of text at a time.
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Type</th>
<th>Displays as</th>
</tr>
</thead>
<tr>
<td>Blockquote</td>
<td>&gt; text</td>
<td><blockquote>text</blockquote></td>
</tr>
<tr>
<td>Headers 1-6</td>
<td># Header 1<br>## Header 2<br>### Header 3<br>#### Header 4<br>##### Header 5<br>###### Header 6</td>
<td><h1>Header 1</h1><h2>Header 2</h2><h3>Header 3</h3><h4>Header 4</h4><h5>Header 5</h5><h6>Header 6</h6></td>
</tr>
<tr>
<td>Ordered list</td>
<td>1. First thing<br>2. Second thing</td>
<td><ol><li>First thing</li><li>Second thing</li></ol></td>
</tr>
<tr>
<td>Unordered list</td>
<td>* First thing<br>* Second thing</td>
<td><ul><li>First thing</li><li>Second thing</li></ul></td>
</tr>
<tr>
<td>Code Block</td>
<td>```<br>Use three backticks above and below.<br>Or, indent the lines with four spaces.<br>```</td>
<td>
</tr>
<tr>
<td>Spoilers</td>
<td>&lt;s&gt; bussy > gussy &lt;/s&gt;</td>
<td><p class="spoiler">bussy > gussy</p></td>
<pre>
Use three backticks above and below.
Or, indent the lines with four spaces.
</pre>
</td>
</tr>
</table>
## Custom Formatting
We also have some custom hooks for mentioning users and subreddits. Note that these only work if the mentioned user or subreddit actually exists.
{% endfilter %}
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Type</th>
<th>Displays as</th>
</tr>
</thead>
<tr>
<td>Username Mention</td>
<td>@QuadNarca</td>
<td><a class="d-inline-block" href="/@QuadNarca"><img src="/@QuadNarca/pic/profile" class="profile-pic-20 mr-1">@QuadNarca</a></td>
</tr>
<tr>
<td>Subreddit Mention</td>
<td>r/{{'SITE_NAME' | app_config}}</td>
<td><a class="d-inline-block" href="https://www.reddit.com/r/{{'SITE_NAME' | app_config}}/">r/{{'SITE_NAME' | app_config}}</a></td>
</tr>
<tr>
<td>Redditor Mention</td>
<td>u/Bardfinn</td>
<td><a class="d-inline-block" href="https://www.reddit.com/u/Bardfinn/">u/Bardfinn</a></td>
</tr>
</table>
{% include "expanded_image_modal.html" %}
{% include "expanded_video_modal.html" %}
<script src="/assets/js/js.js"></script>
{% endblock %}
{% extends "default.html" %}
{% block title %}
<title>{{'SITE_NAME' | app_config}} - Formatting</title>
<meta name="description" content="{{'SITE_NAME' | app_config}} Formatting">
{% endblock %}
{% block content %}
<pre>
</pre>
{% filter markdown %}
# Formatting
On {{'SITE_NAME' | app_config}}, you can use Markdown formatting.
## Inline formatting
{% endfilter %}
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Type</th>
<th>Displays as</th>
</tr>
</thead>
<tr>
<td>Italics</td>
<td>*text*</td>
<td><i>text</i></td>
</tr>
<tr>
<td>Bold</td>
<td>**text**</td>
<td><b>text</b></td>
</tr>
<tr>
<td>Code</td>
<td>`text`</td>
<td><code>text</code></td>
</tr>
<tr>
<td>Strikethrough</td>
<td>~~text~~</td>
<td><del>text</del></td>
</tr>
<tr>
<td>Links</td>
<td>[{{'SITE_NAME' | app_config}}]({{request.host_url}})</td>
<td><a href="{{request.host_url}}">{{'SITE_NAME' | app_config}}</a></td>
</tr>
<tr>
<td>Emojis</td>
<td>:marseylove:</td>
<td><img data-toggle="tooltip" title="marseylove" delay="0" height="20" src="/assets/images/emojis/marseylove.gif"></td>
</tr>
</table>
{% filter markdown %}
## Block formatting
These Markdown tags format an entire paragraph of text at a time.
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Type</th>
<th>Displays as</th>
</tr>
</thead>
<tr>
<td>Blockquote</td>
<td>&gt; text</td>
<td><blockquote>text</blockquote></td>
</tr>
<tr>
<td>Headers 1-6</td>
<td># Header 1<br>## Header 2<br>### Header 3<br>#### Header 4<br>##### Header 5<br>###### Header 6</td>
<td><h1>Header 1</h1><h2>Header 2</h2><h3>Header 3</h3><h4>Header 4</h4><h5>Header 5</h5><h6>Header 6</h6></td>
</tr>
<tr>
<td>Ordered list</td>
<td>1. First thing<br>2. Second thing</td>
<td><ol><li>First thing</li><li>Second thing</li></ol></td>
</tr>
<tr>
<td>Unordered list</td>
<td>* First thing<br>* Second thing</td>
<td><ul><li>First thing</li><li>Second thing</li></ul></td>
</tr>
<tr>
<td>Code Block</td>
<td>```<br>Use three backticks above and below.<br>Or, indent the lines with four spaces.<br>```</td>
<td>
</tr>
<tr>
<td>Spoilers</td>
<td>&lt;s&gt; bussy > gussy &lt;/s&gt;</td>
<td><p class="spoiler">bussy > gussy</p></td>
<pre>
Use three backticks above and below.
Or, indent the lines with four spaces.
</pre>
</td>
</tr>
</table>
## Custom Formatting
We also have some custom hooks for mentioning users and subreddits. Note that these only work if the mentioned user or subreddit actually exists.
{% endfilter %}
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Type</th>
<th>Displays as</th>
</tr>
</thead>
<tr>
<td>Username Mention</td>
<td>@QuadNarca</td>
<td><a class="d-inline-block" href="/@QuadNarca"><img src="/@QuadNarca/pic/profile" class="profile-pic-20 mr-1">@QuadNarca</a></td>
</tr>
<tr>
<td>Subreddit Mention</td>
<td>r/{{'SITE_NAME' | app_config}}</td>
<td><a class="d-inline-block" href="https://www.reddit.com/r/{{'SITE_NAME' | app_config}}/">r/{{'SITE_NAME' | app_config}}</a></td>
</tr>
<tr>
<td>Redditor Mention</td>
<td>u/Bardfinn</td>
<td><a class="d-inline-block" href="https://www.reddit.com/u/Bardfinn/">u/Bardfinn</a></td>
</tr>
</table>
{% include "expanded_image_modal.html" %}
{% include "expanded_video_modal.html" %}
<script src="/assets/js/js.js"></script>
{% endblock %}

View File

@ -134,4 +134,4 @@
</body>
</html>
</html>

View File

@ -1,119 +1,119 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="Sign in to {{'SITE_NAME' | app_config}}">
<meta name="author" content="">
<title>2-Step Login - {{'SITE_NAME' | app_config}}</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- Font Awesome -->
<link href="/assets/fontawesome/css/all.css" rel="stylesheet"> <!--load all styles -->
<script data-search-pseudo-elements defer src="https://use.fontawesome.com/releases/latest/js/js.js"
integrity="sha384-L469/ELG4Bg9sDQbl0hvjMq8pOcqFgkSpwhwnslzvVVGpDjYJ6wJJyYjvG3u8XW7"
crossorigin="anonymous"></script>
<!-- {{'SITE_NAME' | app_config}} CSS -->
<link rel="stylesheet" href="/assets/style/{{'DEFAULT_THEME' | app_config}}.css">
</head>
<body id="login">
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent fixed-top border-0">
<div class="container-fluid">
<button class="navbar-toggler d-none" type="button" data-toggle="collapse" data-target="#navbarResponsive"
aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</nav>
<!-- Page Content -->
<div class="container-fluid position-absolute h-100 p-0 overflow-auto">
<div class="row no-gutters h-100">
<div class="col-12 col-md-6 my-auto p-3">
<div class="row justify-content-center">
<div class="col-10 col-md-7">
<div class="mb-5">
<a href="/" class="text-decoration-none"><span class="h3 text-primary">{{'SITE_NAME' | app_config}}</span></a>
</div>
<div id="login-form" class="">
<h1 class="h2">Two-step login</h1>
<p class="text-muted mb-md-5">To login, please enter the 6-digit verification code generated in your authenticator app.</p>
{% if failed %}
<div class="alert alert-danger alert-dismissible fade show d-flex my-3" role="alert">
<i class="fas fa-exclamation-circle my-auto"></i>
<div>
Invalid verification code. Please try again.
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endif %}
<form action="/login" method="post" class="mt-md-3" id="login">
<input type="hidden" name="username" value="{{v.username}}">
<input type="hidden" name="redirect" value="{{redirect}}">
<input type="hidden" name="time" value="{{time}}">
<input type="hidden" name="hash" value="{{hash}}">
<label for="2fa_token" class="mt-3">Your verification code</label>
<input class="form-control" id="2fa_token" name="2fa_token" type="text" placeholder="6-digit code">
<small><a href="/lost_2fa">Lost your 2FA device?</a></small>
<button class="btn btn-primary login w-100 mt-3" id="login_button">Sign in</button>
</form>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-6 d-none d-md-block">
<div class="splash-wrapper">
<div class="splash-overlay"></div>
<img class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.gif"></img>
</div>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="Sign in to {{'SITE_NAME' | app_config}}">
<meta name="author" content="">
<title>2-Step Login - {{'SITE_NAME' | app_config}}</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- Font Awesome -->
<link href="/assets/fontawesome/css/all.css" rel="stylesheet"> <!--load all styles -->
<script data-search-pseudo-elements defer src="https://use.fontawesome.com/releases/latest/js/js.js"
integrity="sha384-L469/ELG4Bg9sDQbl0hvjMq8pOcqFgkSpwhwnslzvVVGpDjYJ6wJJyYjvG3u8XW7"
crossorigin="anonymous"></script>
<!-- {{'SITE_NAME' | app_config}} CSS -->
<link rel="stylesheet" href="/assets/style/{{'DEFAULT_THEME' | app_config}}.css">
</head>
<body id="login">
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent fixed-top border-0">
<div class="container-fluid">
<button class="navbar-toggler d-none" type="button" data-toggle="collapse" data-target="#navbarResponsive"
aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</nav>
<!-- Page Content -->
<div class="container-fluid position-absolute h-100 p-0 overflow-auto">
<div class="row no-gutters h-100">
<div class="col-12 col-md-6 my-auto p-3">
<div class="row justify-content-center">
<div class="col-10 col-md-7">
<div class="mb-5">
<a href="/" class="text-decoration-none"><span class="h3 text-primary">{{'SITE_NAME' | app_config}}</span></a>
</div>
<div id="login-form" class="">
<h1 class="h2">Two-step login</h1>
<p class="text-muted mb-md-5">To login, please enter the 6-digit verification code generated in your authenticator app.</p>
{% if failed %}
<div class="alert alert-danger alert-dismissible fade show d-flex my-3" role="alert">
<i class="fas fa-exclamation-circle my-auto"></i>
<div>
Invalid verification code. Please try again.
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endif %}
<form action="/login" method="post" class="mt-md-3" id="login">
<input type="hidden" name="username" value="{{v.username}}">
<input type="hidden" name="redirect" value="{{redirect}}">
<input type="hidden" name="time" value="{{time}}">
<input type="hidden" name="hash" value="{{hash}}">
<label for="2fa_token" class="mt-3">Your verification code</label>
<input class="form-control" id="2fa_token" name="2fa_token" type="text" placeholder="6-digit code">
<small><a href="/lost_2fa">Lost your 2FA device?</a></small>
<button class="btn btn-primary login w-100 mt-3" id="login_button">Sign in</button>
</form>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-6 d-none d-md-block">
<div class="splash-wrapper">
<div class="splash-overlay"></div>
<img class="splash-img" src="/assets/images/{{'SITE_NAME' | app_config}}/cover.gif"></img>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -260,4 +260,4 @@
</body>
</html
</html>

View File

@ -233,4 +233,4 @@
</body>
</html
</html>

View File

@ -229,4 +229,4 @@
</body>
</html>
</html>

View File

@ -148,4 +148,4 @@
</body>
</html>
</html>

View File

@ -1,466 +1,466 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include "bootstrap.html" %}
<script>
$(document).ready(function() {
$('#submitform').submit(function() {
// disable button
$("#create_button").prop("disabled", true);
// add spinner to button
$("#create_button").html('<span class="spinner-border spinner-border-sm mr-2" role="status" aria-hidden="true"></span>Creating post');
});
});
// Text Formatting
// Bold Text
makeBold = function (form) {
var text = document.getElementById(form);
var startIndex = text.selectionStart,
endIndex = text.selectionEnd;
var selectedText = text.value.substring(startIndex, endIndex);
var format = '**'
if (selectedText.includes('**')) {
text.value = selectedText.replace(/\*/g, '');
}
else if (selectedText.length == 0) {
text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex);
}
else {
text.value = text.value.substring(0, startIndex) + format + selectedText + format + text.value.substring(endIndex);
}
}
// Italicize Comment Text
makeItalics = function (form) {
var text = document.getElementById(form);
var startIndex = text.selectionStart,
endIndex = text.selectionEnd;
var selectedText = text.value.substring(startIndex, endIndex);
var format = '*'
if (selectedText.includes('*')) {
text.value = selectedText.replace(/\*/g, '');
}
else if (selectedText.length == 0) {
text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex);
}
else {
text.value = text.value.substring(0, startIndex) + format + selectedText + format + text.value.substring(endIndex);
}
}
// Quote Comment Text
makeQuote = function (form) {
var text = document.getElementById(form);
var startIndex = text.selectionStart,
endIndex = text.selectionEnd;
var selectedText = text.value.substring(startIndex, endIndex);
var format = '>'
if (selectedText.includes('>')) {
text.value = text.value.substring(0, startIndex) + selectedText.replace(/\>/g, '') + text.value.substring(endIndex);
}
else if (selectedText.length == 0) {
text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex);
}
else {
text.value = text.value.substring(0, startIndex) + format + selectedText + text.value.substring(endIndex);
}
}
// Character Count
function charLimit(form, text) {
var input = document.getElementById(form);
var text = document.getElementById(text);
var length = input.value.length;
var maxLength = input.getAttribute("maxlength");
if (length >= maxLength) {
text.style.color = "#E53E3E";
}
else if (length >= maxLength * .72){
text.style.color = "#FFC107";
}
else {
text.style.color = "#A0AEC0";
}
text.innerText = maxLength - length;
}
//part of submit page js
hide_image=function(){
x=document.getElementById('image-upload-block');
url=document.getElementById('post-URL').value;
if (url.length>=1){
x.classList.add('d-none');
}
else {
x.classList.remove('d-none');
}
}
// Auto-suggest title given URL
function autoSuggestTitle() {
var urlField = document.getElementById("post-URL");
var titleField = document.getElementById("post-title");
var isValidURL = urlField.checkValidity();
if (isValidURL && urlField.value.length > 0 && titleField.value === "") {
var x = new XMLHttpRequest();
x.withCredentials=true;
x.onreadystatechange = function() {
if (x.readyState == 4 && x.status == 200) {
title=JSON.parse(x.responseText)["title"];
titleField.value=title;
checkForRequired()
}
}
x.open('get','/submit/title?url=' + urlField.value);
x.send(null);
};
};
// Run AutoSuggestTitle function on load
if (window.location.pathname=='/submit') {
window.onload = autoSuggestTitle();
}
// Paste to create submission
document.addEventListener('paste', function (event) {
var nothingFocused = document.activeElement === document.body;
if (nothingFocused) {
var clipText = event.clipboardData.getData('Text');
var url = new RegExp('^(?:[a-z]+:)?//', 'i');
if (url.test(clipText) && window.location.pathname !== '/submit') {
window.location.href = '/submit?url=' + clipText;
}
else if (url.test(clipText) && window.location.pathname == '/submit') {
document.getElementById("post-URL").value = clipText;
autoSuggestTitle()
}
}
});
// Submit Page Front-end Validation
function checkForRequired() {
// Divs
var title = document.getElementById("post-title");
var url = document.getElementById("post-URL");
var text = document.getElementById("post-text");
var button = document.getElementById("create_button");
var image = document.getElementById("file-upload");
// Toggle reuqired attribute
if (url.value.length > 0 || image.value.length > 0) {
text.required = false;
url.required=false;
} else if (text.value.length > 0 || image.value.length > 0) {
url.required = false;
} else {
text.required = true;
url.required = true;
}
// Validity check
var isValidTitle = title.checkValidity();
var isValidURL = url.checkValidity();
var isValidText = text.checkValidity();
// Disable submit button if invalid inputs
if (isValidTitle && (isValidURL || image.value.length>0)) {
button.disabled = false;
} else if (isValidTitle && isValidText) {
button.disabled = false;
} else {
button.disabled = true;
}
}
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/favicon.gif">
{% include "emoji_modal.html" %}
{% include "gif_modal.html" %}
{% block title %}
<title>Create a post - {{'SITE_NAME' | app_config}}</title>
{% endblock %}
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap" rel="stylesheet">
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- {{'SITE_NAME' | app_config}} Board CSS -->
{% block stylesheets %}
{% if v %}
<link rel="stylesheet" href="/assets/style/{{v.theme}}_{{v.themecolor}}.css">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/style/agendaposter.css">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
{% else %}
<link rel="stylesheet" href="/assets/style/{{'DEFAULT_THEME' | app_config}}.css">
{% endif %}
{% endblock %}
<!-- Font Awesome -->
<link href="/assets/style/fa.css" rel="stylesheet"> <!--load all styles -->
{% if v %}
<script>
function post(url, callback, errortext) {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
var form = new FormData()
form.append("formkey", "{{v.formkey}}");
xhr.withCredentials=true;
xhr.onload=callback
xhr.onerror=function(){alert(errortext)}
xhr.send(form);
}
function formkey() {
return '{{v.formkey}}';
}
</script>
{% endif %}
</head>
<body id="submit" style="overflow-x: hidden; {% if v and v.background %} background:url(/assets/images/backgrounds/{{v.background}}) no-repeat center center fixed !important; background-size: cover!important; background-color: #000!important;{% endif %}">
<!-- Navigation -->
{% include "header.html" %}
{% block form %}
<!-- Page Content -->
<form id="submitform" action="/submit" method="post" enctype="multipart/form-data">
<div class="container">
<div class="row justify-content-center mb-4 pb-7">
<div class="col col-md-6 p-3 py-md-0">
<h1 class="d-none d-md-block">Create a post</h1>
<h2 class="h3 d-md-none">Create a post</h2>
<div class="body">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<label for="title">Post Title</label>
<input class="form-control" id="post-title" aria-describedby="titleHelpRegister" type="text" name="title" placeholder="Required" value="{{title}}" minlength="1" maxlength="500" required oninput="checkForRequired()">
<div id="urlblock">
<label for="URL" class="mt-3">URL</label>
<input class="form-control" id="post-URL" aria-describedby="URLHelp" type="url" name="url" placeholder="Optional if you have text." value="{{request.args.get('url','')}}" required oninput="checkForRequired();autoSuggestTitle();hide_image()">
<small class="form-text text-muted">To post an image, use a direct image link such as i.imgur.com</small>
</div>
<div id="image-upload-block">
<div><label class="mt-3">Image Upload</label></div>
<img id="image-preview" class="w-100 d-block">
<label class="btn btn-secondary m-0" for="file-upload">
<div id="filename-show">Select Image</div>
<input id="file-upload" type="file" name="file" accept="image/*" hidden>
</label>
<small class="form-text text-muted">Images uploaded will be public. Optional if you have text.</small>
</div>
</div>
<label for="body" class="mt-3">Text<i class="fas fa-info-circle text-gray-400 ml-1" data-toggle="tooltip" data-placement="top" title="Uses markdown. Limited to 10000 characters."></i></label>
<div class="input-group">
<textarea form="submitform" id="post-text" class="form-control rounded" aria-label="With textarea" placeholder="Optional if you have a link or an image." rows="3" name="body" oninput="charLimit('post-text','character-count-submit-text-form');checkForRequired()" maxlength="10000" required>{{text}}</textarea>
<span class="position-absolute text-small font-weight-bold" id="character-count-submit-text-form" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></span>
<div class="bg-light text-format d-none">
<small class="format"><i class="fas fa-bold"></i></small>
<small class="format"><i class="fas fa-italic"></i></small>
<small class="format"><i class="fas fa-quote-right"></i></small>
<small class="format"><i class="fas fa-link"></i></small>
</div>
</div>
<p></p>
<small class="btn btn-secondary format d-inline-block m-0">
<i class="fas fa-bold" aria-hidden="true" onclick="makeBold('post-text')" data-toggle="tooltip" data-placement="bottom" title="Bold"></i>
</small>
&nbsp;
<small class="btn btn-secondary format d-inline-block m-0">
<i class="fas fa-italic" aria-hidden="true" onclick="makeItalics('post-text')" data-toggle="tooltip" data-placement="bottom" title="Italicize"></i>
</small>
&nbsp;
<small class="btn btn-secondary format d-inline-block m-0">
<i class="fas fa-quote-right" aria-hidden="true" onclick="makeQuote('post-text')" data-toggle="tooltip" data-placement="bottom" title="Quote"></i>
</small>
&nbsp;
<small class="btn btn-secondary format d-inline-block m-0"><span class="font-weight-bolder text-uppercase" aria-hidden="true" onclick="getGif();commentForm('post-text')" data-toggle="modal" data-target="#gifModal" data-toggle="tooltip" data-placement="bottom" title="Add GIF">GIF</span></small>
&nbsp;
<label class="btn btn-secondary format d-inline-block m-0" for="emoji-reply-btn">
<div id="emoji-reply-btn" onclick="loadEmojis('post-text')" aria-hidden="true" data-toggle="modal" data-target="#emojiModal" data-toggle="tooltip" data-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></div>
</label>
<pre></pre>
<div class="form-text text-small"><a href="/formatting" target="_blank">Formatting help</a></div>
<pre></pre>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="nsfwCheck" name="over_18">
<label class="custom-control-label" for="nsfwCheck">+18</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="privateCheck" name="private">
<label class="custom-control-label" for="privateCheck">Unlisted</label>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row fixed-bottom bg-white border-top p-3" id="" style="z-index: 100; bottom: 0px; transition: bottom 220ms cubic-bezier(0, 0, 0.2, 1) 0s;">
<div class="col">
<a href="/" class="btn btn-secondary">Cancel</a>
</div>
<div class="col text-right">
{% if error %}<span class="text-danger mr-2">{{error}}</span>{% endif %}
<button class="btn btn-outline-purple" id="create_button" type="submit" disabled>Post</button>
</div>
</div>
</div>
</form>
{% endblock %}
<!-- {{'SITE_NAME' | app_config}} JS -->
<script src="/assets/js/js.js"></script>
<!-- ClipboardJS -->
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<!-- Instantiate clipboard by passing a string selector -->
<script>
var clipboard = new ClipboardJS('.copy-link');
clipboard.on('success', function(e) {
jQuery(function($) {
$('#toast-success').toast('show');
})
console.log(e);
});
clipboard.on('error', function(e) {
jQuery(function($) {
$('#toast-error').toast('show');
})
console.log(e);
});
document.onpaste = function(event) {
f=document.getElementById('file-upload');
files = event.clipboardData.files
filename = files[0].name.toLowerCase()
if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png") || filename.endsWith(".gif"))
{
f.files = files;
$('#filename-show').text(filename);
$('#urlblock').addClass('d-none');
var fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {$('#image-preview').attr('src', this.result);});
$('#file-upload').attr('required', false);
checkForRequired();
}
}
$('#file-upload').on('change', function(e){
f=document.getElementById('file-upload');
$('#urlblock').addClass('d-none');
$('#filename-show').text($('#file-upload')[0].files[0].name);
var fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {$('#image-preview').attr('src', this.result);});
checkForRequired();
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
{% include "bootstrap.html" %}
<script>
$(document).ready(function() {
$('#submitform').submit(function() {
// disable button
$("#create_button").prop("disabled", true);
// add spinner to button
$("#create_button").html('<span class="spinner-border spinner-border-sm mr-2" role="status" aria-hidden="true"></span>Creating post');
});
});
// Text Formatting
// Bold Text
makeBold = function (form) {
var text = document.getElementById(form);
var startIndex = text.selectionStart,
endIndex = text.selectionEnd;
var selectedText = text.value.substring(startIndex, endIndex);
var format = '**'
if (selectedText.includes('**')) {
text.value = selectedText.replace(/\*/g, '');
}
else if (selectedText.length == 0) {
text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex);
}
else {
text.value = text.value.substring(0, startIndex) + format + selectedText + format + text.value.substring(endIndex);
}
}
// Italicize Comment Text
makeItalics = function (form) {
var text = document.getElementById(form);
var startIndex = text.selectionStart,
endIndex = text.selectionEnd;
var selectedText = text.value.substring(startIndex, endIndex);
var format = '*'
if (selectedText.includes('*')) {
text.value = selectedText.replace(/\*/g, '');
}
else if (selectedText.length == 0) {
text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex);
}
else {
text.value = text.value.substring(0, startIndex) + format + selectedText + format + text.value.substring(endIndex);
}
}
// Quote Comment Text
makeQuote = function (form) {
var text = document.getElementById(form);
var startIndex = text.selectionStart,
endIndex = text.selectionEnd;
var selectedText = text.value.substring(startIndex, endIndex);
var format = '>'
if (selectedText.includes('>')) {
text.value = text.value.substring(0, startIndex) + selectedText.replace(/\>/g, '') + text.value.substring(endIndex);
}
else if (selectedText.length == 0) {
text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex);
}
else {
text.value = text.value.substring(0, startIndex) + format + selectedText + text.value.substring(endIndex);
}
}
// Character Count
function charLimit(form, text) {
var input = document.getElementById(form);
var text = document.getElementById(text);
var length = input.value.length;
var maxLength = input.getAttribute("maxlength");
if (length >= maxLength) {
text.style.color = "#E53E3E";
}
else if (length >= maxLength * .72){
text.style.color = "#FFC107";
}
else {
text.style.color = "#A0AEC0";
}
text.innerText = maxLength - length;
}
//part of submit page js
hide_image=function(){
x=document.getElementById('image-upload-block');
url=document.getElementById('post-URL').value;
if (url.length>=1){
x.classList.add('d-none');
}
else {
x.classList.remove('d-none');
}
}
// Auto-suggest title given URL
function autoSuggestTitle() {
var urlField = document.getElementById("post-URL");
var titleField = document.getElementById("post-title");
var isValidURL = urlField.checkValidity();
if (isValidURL && urlField.value.length > 0 && titleField.value === "") {
var x = new XMLHttpRequest();
x.withCredentials=true;
x.onreadystatechange = function() {
if (x.readyState == 4 && x.status == 200) {
title=JSON.parse(x.responseText)["title"];
titleField.value=title;
checkForRequired()
}
}
x.open('get','/submit/title?url=' + urlField.value);
x.send(null);
};
};
// Run AutoSuggestTitle function on load
if (window.location.pathname=='/submit') {
window.onload = autoSuggestTitle();
}
// Paste to create submission
document.addEventListener('paste', function (event) {
var nothingFocused = document.activeElement === document.body;
if (nothingFocused) {
var clipText = event.clipboardData.getData('Text');
var url = new RegExp('^(?:[a-z]+:)?//', 'i');
if (url.test(clipText) && window.location.pathname !== '/submit') {
window.location.href = '/submit?url=' + clipText;
}
else if (url.test(clipText) && window.location.pathname == '/submit') {
document.getElementById("post-URL").value = clipText;
autoSuggestTitle()
}
}
});
// Submit Page Front-end Validation
function checkForRequired() {
// Divs
var title = document.getElementById("post-title");
var url = document.getElementById("post-URL");
var text = document.getElementById("post-text");
var button = document.getElementById("create_button");
var image = document.getElementById("file-upload");
// Toggle reuqired attribute
if (url.value.length > 0 || image.value.length > 0) {
text.required = false;
url.required=false;
} else if (text.value.length > 0 || image.value.length > 0) {
url.required = false;
} else {
text.required = true;
url.required = true;
}
// Validity check
var isValidTitle = title.checkValidity();
var isValidURL = url.checkValidity();
var isValidText = text.checkValidity();
// Disable submit button if invalid inputs
if (isValidTitle && (isValidURL || image.value.length>0)) {
button.disabled = false;
} else if (isValidTitle && isValidText) {
button.disabled = false;
} else {
button.disabled = true;
}
}
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" href="/assets/images/{{'SITE_NAME' | app_config}}/favicon.gif">
{% include "emoji_modal.html" %}
{% include "gif_modal.html" %}
{% block title %}
<title>Create a post - {{'SITE_NAME' | app_config}}</title>
{% endblock %}
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap" rel="stylesheet">
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- {{'SITE_NAME' | app_config}} Board CSS -->
{% block stylesheets %}
{% if v %}
<link rel="stylesheet" href="/assets/style/{{v.theme}}_{{v.themecolor}}.css">
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/style/agendaposter.css">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
{% else %}
<link rel="stylesheet" href="/assets/style/{{'DEFAULT_THEME' | app_config}}.css">
{% endif %}
{% endblock %}
<!-- Font Awesome -->
<link href="/assets/style/fa.css" rel="stylesheet"> <!--load all styles -->
{% if v %}
<script>
function post(url, callback, errortext) {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
var form = new FormData()
form.append("formkey", "{{v.formkey}}");
xhr.withCredentials=true;
xhr.onload=callback
xhr.onerror=function(){alert(errortext)}
xhr.send(form);
}
function formkey() {
return '{{v.formkey}}';
}
</script>
{% endif %}
</head>
<body id="submit" style="overflow-x: hidden; {% if v and v.background %} background:url(/assets/images/backgrounds/{{v.background}}) no-repeat center center fixed !important; background-size: cover!important; background-color: #000!important;{% endif %}">
<!-- Navigation -->
{% include "header.html" %}
{% block form %}
<!-- Page Content -->
<form id="submitform" action="/submit" method="post" enctype="multipart/form-data">
<div class="container">
<div class="row justify-content-center mb-4 pb-7">
<div class="col col-md-6 p-3 py-md-0">
<h1 class="d-none d-md-block">Create a post</h1>
<h2 class="h3 d-md-none">Create a post</h2>
<div class="body">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<label for="title">Post Title</label>
<input class="form-control" id="post-title" aria-describedby="titleHelpRegister" type="text" name="title" placeholder="Required" value="{{title}}" minlength="1" maxlength="500" required oninput="checkForRequired()">
<div id="urlblock">
<label for="URL" class="mt-3">URL</label>
<input class="form-control" id="post-URL" aria-describedby="URLHelp" type="url" name="url" placeholder="Optional if you have text." value="{{request.args.get('url','')}}" required oninput="checkForRequired();autoSuggestTitle();hide_image()">
<small class="form-text text-muted">To post an image, use a direct image link such as i.imgur.com</small>
</div>
<div id="image-upload-block">
<div><label class="mt-3">Image Upload</label></div>
<img id="image-preview" class="w-100 d-block">
<label class="btn btn-secondary m-0" for="file-upload">
<div id="filename-show">Select Image</div>
<input id="file-upload" type="file" name="file" accept="image/*" hidden>
</label>
<small class="form-text text-muted">Images uploaded will be public. Optional if you have text.</small>
</div>
</div>
<label for="body" class="mt-3">Text<i class="fas fa-info-circle text-gray-400 ml-1" data-toggle="tooltip" data-placement="top" title="Uses markdown. Limited to 10000 characters."></i></label>
<div class="input-group">
<textarea form="submitform" id="post-text" class="form-control rounded" aria-label="With textarea" placeholder="Optional if you have a link or an image." rows="3" name="body" oninput="charLimit('post-text','character-count-submit-text-form');checkForRequired()" maxlength="10000" required>{{text}}</textarea>
<span class="position-absolute text-small font-weight-bold" id="character-count-submit-text-form" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></span>
<div class="bg-light text-format d-none">
<small class="format"><i class="fas fa-bold"></i></small>
<small class="format"><i class="fas fa-italic"></i></small>
<small class="format"><i class="fas fa-quote-right"></i></small>
<small class="format"><i class="fas fa-link"></i></small>
</div>
</div>
<p></p>
<small class="btn btn-secondary format d-inline-block m-0">
<i class="fas fa-bold" aria-hidden="true" onclick="makeBold('post-text')" data-toggle="tooltip" data-placement="bottom" title="Bold"></i>
</small>
&nbsp;
<small class="btn btn-secondary format d-inline-block m-0">
<i class="fas fa-italic" aria-hidden="true" onclick="makeItalics('post-text')" data-toggle="tooltip" data-placement="bottom" title="Italicize"></i>
</small>
&nbsp;
<small class="btn btn-secondary format d-inline-block m-0">
<i class="fas fa-quote-right" aria-hidden="true" onclick="makeQuote('post-text')" data-toggle="tooltip" data-placement="bottom" title="Quote"></i>
</small>
&nbsp;
<small class="btn btn-secondary format d-inline-block m-0"><span class="font-weight-bolder text-uppercase" aria-hidden="true" onclick="getGif();commentForm('post-text')" data-toggle="modal" data-target="#gifModal" data-toggle="tooltip" data-placement="bottom" title="Add GIF">GIF</span></small>
&nbsp;
<label class="btn btn-secondary format d-inline-block m-0" for="emoji-reply-btn">
<div id="emoji-reply-btn" onclick="loadEmojis('post-text')" aria-hidden="true" data-toggle="modal" data-target="#emojiModal" data-toggle="tooltip" data-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></div>
</label>
<pre></pre>
<div class="form-text text-small"><a href="/formatting" target="_blank">Formatting help</a></div>
<pre></pre>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="nsfwCheck" name="over_18">
<label class="custom-control-label" for="nsfwCheck">+18</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="privateCheck" name="private">
<label class="custom-control-label" for="privateCheck">Unlisted</label>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row fixed-bottom bg-white border-top p-3" id="" style="z-index: 100; bottom: 0px; transition: bottom 220ms cubic-bezier(0, 0, 0.2, 1) 0s;">
<div class="col">
<a href="/" class="btn btn-secondary">Cancel</a>
</div>
<div class="col text-right">
{% if error %}<span class="text-danger mr-2">{{error}}</span>{% endif %}
<button class="btn btn-outline-purple" id="create_button" type="submit" disabled>Post</button>
</div>
</div>
</div>
</form>
{% endblock %}
<!-- {{'SITE_NAME' | app_config}} JS -->
<script src="/assets/js/js.js"></script>
<!-- ClipboardJS -->
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<!-- Instantiate clipboard by passing a string selector -->
<script>
var clipboard = new ClipboardJS('.copy-link');
clipboard.on('success', function(e) {
jQuery(function($) {
$('#toast-success').toast('show');
})
console.log(e);
});
clipboard.on('error', function(e) {
jQuery(function($) {
$('#toast-error').toast('show');
})
console.log(e);
});
document.onpaste = function(event) {
f=document.getElementById('file-upload');
files = event.clipboardData.files
filename = files[0].name.toLowerCase()
if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png") || filename.endsWith(".gif"))
{
f.files = files;
$('#filename-show').text(filename);
$('#urlblock').addClass('d-none');
var fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {$('#image-preview').attr('src', this.result);});
$('#file-upload').attr('required', false);
checkForRequired();
}
}
$('#file-upload').on('change', function(e){
f=document.getElementById('file-upload');
$('#urlblock').addClass('d-none');
$('#filename-show').text($('#file-upload')[0].files[0].name);
var fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {$('#image-preview').attr('src', this.result);});
checkForRequired();
})
</script>
</body>
</html>