2021-08-22 17:00:07 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
{% include "bootstrap.html" %}
2021-09-02 19:16:15 +00:00
< script src = "https://cdn.jsdelivr.net/npm/vue@2.6.14" > < / script >
< script src = "https://cdn.jsdelivr.net/remarkable/1.7.1/remarkable.min.js" > < / script >
2021-08-22 17:00:07 +00:00
< 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 = "" >
2021-08-28 11:51:26 +00:00
< link rel = "icon" type = "image/png" href = "/assets/images/{{'SITE_NAME' | app_config}}/icon.gif" >
2021-08-22 17:00:07 +00:00
{% 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 >
2021-09-02 19:16:15 +00:00
< 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 %}display: block;" >
2021-08-22 17:00:07 +00:00
<!-- Navigation -->
{% include "header.html" %}
{% block form %}
<!-- Page Content -->
2021-09-02 19:16:15 +00:00
< div id = "submitapp" class = "submit-grid-view" >
2021-09-02 19:37:17 +00:00
< form id = "submitform" action = "/submit" method = "post" enctype = "multipart/form-data" style = "grid-column: 2" >
2021-08-22 17:00:07 +00:00
< div class = "container" >
2021-09-02 19:16:15 +00:00
< div class = "row justify-content-center mb-5" >
2021-08-22 17:00:07 +00:00
2021-09-02 19:16:15 +00:00
< div class = "col p-3 py-md-0" >
2021-08-22 17:00:07 +00:00
2021-09-02 19:39:31 +00:00
< h1 class = "d-none d-md-block mt-3" > Create a post< / h1 >
2021-08-22 17:00:07 +00:00
< h2 class = "h3 d-md-none" > Create a post< / h2 >
< div class = "body" >
< input type = "hidden" name = "formkey" value = "{{v.formkey}}" >
2021-09-03 17:03:25 +00:00
< label for = "title" > Post Title< / label >
2021-08-22 17:00:07 +00:00
2021-09-03 19:07:51 +00:00
< 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()" >
2021-08-22 17:00:07 +00:00
2021-09-03 19:02:51 +00:00
< label class = "btn btn-secondary format d-inline-block m-0" for = "emoji-reply-btn-2" >
< div id = "emoji-reply-btn-2" onclick = "loadEmojis('post-title')" 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 >
2021-08-22 17:00:07 +00:00
< div id = "urlblock" >
2021-09-03 17:03:25 +00:00
< label for = "URL" class = "mt-3" > URL< / label >
2021-08-22 17:00:07 +00:00
< 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 >
2021-09-03 14:08:32 +00:00
< img loading = "lazy" id = "image-preview" class = "w-100 d-block" >
2021-08-22 17:00:07 +00:00
2021-09-03 17:03:25 +00:00
< label class = "btn btn-secondary m-0" for = "file-upload" >
2021-08-22 17:00:07 +00:00
< 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 >
2021-09-03 17:03:25 +00:00
< 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 >
2021-08-22 17:00:07 +00:00
< div class = "input-group" >
2021-09-02 19:16:15 +00:00
< textarea v-model = "post_body" 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 >
2021-08-22 17:00:07 +00:00
< 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 >
< 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 >
< 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 >
< 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 >
2021-09-03 17:03:25 +00:00
< label class = "btn btn-secondary format d-inline-block m-0" for = "emoji-reply-btn" >
2021-08-22 17:00:07 +00:00
< 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 >
2021-09-02 19:16:15 +00:00
< div class = "btn btn-secondary" @ click = "togglePreview()" style = "float: right;" >
[[ show_preview ? 'Hide preview' : 'Show preview' ]]
< / div >
2021-08-22 17:00:07 +00:00
< 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" >
2021-09-03 17:03:25 +00:00
< label class = "custom-control-label" for = "nsfwCheck" > +18< / label >
2021-08-22 17:00:07 +00:00
< / div >
< div class = "custom-control custom-checkbox" >
< input type = "checkbox" class = "custom-control-input" id = "privateCheck" name = "private" >
2021-09-03 17:03:25 +00:00
< label class = "custom-control-label" for = "privateCheck" > Draft< / label >
2021-08-22 17:00:07 +00:00
< / div >
2021-09-03 01:34:16 +00:00
< pre >
2021-09-05 22:56:11 +00:00
2021-09-03 01:34:16 +00:00
< / pre >
2021-08-22 17:00:07 +00:00
< / 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 >
2021-09-02 19:16:15 +00:00
< / form >
2021-08-22 17:00:07 +00:00
2021-09-02 19:16:15 +00:00
< div v-show = "show_preview" class = "card-blank" id = "submit-page" style = "height:max-content; min-height: 25rem; transition: 15s;" >
< h1 class = "m-3" > Markdown Preview< / h1 >
< hr >
< div class = "m-3" >
< div id = "post-body-markdown" v-html = "post_body_markdown" style = "max-height: 500px; overflow-y: scroll;" > < / div >
< / div >
< / div >
< / div >
2021-08-22 17:00:07 +00:00
{% endblock %}
2021-09-02 19:16:15 +00:00
< style >
@media(min-width: 768px){
.submit-grid-view{
display: grid;
grid-template-columns: 1fr 3fr 3fr 1fr;
grid-column-gap: 1rem;
}
}
#post-body-markdown img{
max-height: 100px !important;
max-width: 100px !important;
border-radius: 0.35rem;
margin: 0.5rem 0;
}
< / style >
< script >
var md = new Remarkable();
new Vue({
el: "#submitapp",
delimiters: ['[[', ']]'],
data: {
post_body: "",
2021-09-03 19:00:04 +00:00
post_tag: "",
2021-09-02 19:16:15 +00:00
show_preview: false,
},
computed: {
post_body_markdown: function(){
2021-09-03 19:00:04 +00:00
markdown = md.render(this.post_body)
emojis = Array.from(markdown.matchAll(/:(.{1,30}?):/gi))
if(emojis != null){
for(i = 0; i < emojis.length ; i + + ) {
markdown = markdown.replace(emojis[i][0], "< img height = 30 src = '/assets/images/emojis/" + emojis[i][1] + ".gif' > ")
}
}
return markdown
2021-09-02 19:16:15 +00:00
}
},
methods: {
togglePreview() {
this.show_preview = !this.show_preview
}
}
})
< / script >
2021-08-22 17:00:07 +00:00
<!-- {{'SITE_NAME' | app_config}} JS -->
2021-09-05 19:59:09 +00:00
< script src = "/assets/js/general11.js" > < / script >
2021-08-22 17:00:07 +00:00
<!-- 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 >
2021-09-02 19:37:17 +00:00
< / html >