Added admin ajax
This commit is contained in:
parent
3eb02b0509
commit
dc4958087e
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,4 +11,4 @@
|
||||
/fp-content/attachs
|
||||
/fp-content/images
|
||||
/fp-content_
|
||||
/fp-content__
|
||||
/fp-content__
|
12
admin/adminAjaxOperations.php
Normal file
12
admin/adminAjaxOperations.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/* An admin AJAX Functions */
|
||||
|
||||
$AjaxFunctionMap = [];
|
||||
|
||||
$AjaxFunctionHelloWorld = function($args) { /* Just for testing */
|
||||
returnJSONValue(AJAXSUCCESS, 'Hello World : '.$args[0]);
|
||||
};
|
||||
|
||||
$AjaxFunctionMap['Hello World'] = $AjaxFunctionHelloWorld;
|
||||
|
||||
?>
|
@ -39,6 +39,7 @@
|
||||
<script src="{$smarty.const.BLOG_BASEURL}/fp-includes/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<!-- Here is the SCEditor -->
|
||||
<link rel="stylesheet" type="text/css" href="{$smarty.const.BLOG_BASEURL}/admin/res/sceditor/themes/square.min.css">
|
||||
<script src="{$smarty.const.BLOG_BASEURL}/admin/res/sceditor/sceditor.min.js"></script>
|
||||
{if $sce_display=='bbcode'}
|
||||
<script src="{$smarty.const.BLOG_BASEURL}/admin/res/sceditor/formats/bbcode.js"></script>
|
||||
@ -46,22 +47,22 @@
|
||||
<script src="{$smarty.const.BLOG_BASEURL}/admin/res/sceditor/formats/xhtml.js"></script>
|
||||
{/if}
|
||||
<script src="{$smarty.const.BLOG_BASEURL}/fp-interface/lang/{$lang_locale}/sceditor.js"></script>
|
||||
<script src="{$smarty.const.BLOG_BASEURL}/admin/res/sceditor/plugins/flatPressFileManager.js"></script>
|
||||
<script>
|
||||
// Replace the textarea #example with SCEditor
|
||||
var sce_display = "{$sceditor_display}";
|
||||
var lang_editor = "{$lang_locale}";
|
||||
var eRoot = "admin/res/sceditor/";
|
||||
var FileManagerDir = "{$smarty.const.BLOG_BASEURL}/fp-plugins/sceditorfilemanager";
|
||||
{literal}
|
||||
var textarea = document.getElementById('content_textarea');
|
||||
sceditor.create(textarea, {
|
||||
plugins: 'flatPressFileManager',
|
||||
toolbar: 'bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,flatPressFileManager,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source',
|
||||
emoticonsRoot: eRoot,
|
||||
format: sce_display,
|
||||
height: "400px",
|
||||
locale: lang_editor
|
||||
//style: '../../res/sceditor/themes/content/default.min.css'
|
||||
});
|
||||
set_media_button(FileManagerDir);
|
||||
</script>
|
||||
{/literal}
|
||||
{/if}
|
||||
@ -139,7 +140,7 @@
|
||||
|
||||
<!-- Bootstrap Modal (Open the editor) -->
|
||||
<div class="modal fade" id="flatpress-files-modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">File Manager</h5>
|
||||
|
@ -713,4 +713,8 @@ img {
|
||||
#flatpress-files-modal .modal-header {
|
||||
background-color: #aa4142;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sceditor-button-flatPressFileManager div {
|
||||
background-position: 0px -416px !important;
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,3 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
||||
!function(e){"use strict";var t="sce-autodraft-"+location.pathname+location.search;function i(e){localStorage.removeItem(e||t)}e.plugins.autosave=function(){var a,e=this,o=t,r=864e5,n=function(e){localStorage.setItem(o,JSON.stringify(e))},s=function(){return JSON.parse(localStorage.getItem(o))};e.init=function(){var e=(a=this).opts&&a.opts.autosave||{};n=e.save||n,s=e.load||s,o=e.storageKey||o,r=e.expires||r,function(){for(var e=0;e<localStorage.length;e++){var t=localStorage.key(e);if(/^sce\-autodraft\-/.test(t)){var a=JSON.parse(localStorage.getItem(o));a&&a.time<Date.now()-r&&i(t)}}}()},e.signalReady=function(){for(var e=a.getContentAreaContainer();e;){if(/form/i.test(e.nodeName)){e.addEventListener("submit",i.bind(null,o),!0);break}e=e.parentNode}var t=s();t&&(a.sourceMode(t.sourceMode),a.val(t.value,!1),a.focus(),t.sourceMode?a.sourceEditorCaret(t.caret):a.getRangeHelper().restoreRange()),n({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:a.val(null,!1),time:Date.now()})},e.signalValuechangedEvent=function(e){n({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:e.detail.rawValue,time:Date.now()})}},e.plugins.autosave.clear=i}(sceditor);
|
@ -1,3 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
||||
!function(u,e){"use strict";var a=e.dom,c=/(^|\s)(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/watch\?v=)([^"&?\/ ]{11})(?:\&[\&_\?0-9a-z\#]+)?(\s|$)/i;e.plugins.autoyoutube=function(){this.signalPasteRaw=function(e){if(!a.closest(this.currentNode(),"code")&&(e.html||e.text)){var t=u.createElement("div");e.html?t.innerHTML=e.html:t.textContent=e.text,function e(t){for(var o,n=t.firstChild;n;){if(3===n.nodeType){var i=n.nodeValue,r=n.parentNode,s=i.match(c);s&&(r.insertBefore(u.createTextNode(i.substr(0,s.index)+s[1]),n),r.insertBefore(a.parseHTML('<iframe width="560" height="315" frameborder="0" src="https://www.youtube-nocookie.com/embed/'+(o=s[2])+'" data-youtube-id="'+o+'" allowfullscreen></iframe>'),n),n.nodeValue=s[3]+i.substr(s.index+s[0].length))}else a.is(n,"code")||e(n);n=n.nextSibling}}(t),e.html=t.innerHTML}}}}(document,sceditor);
|
3
admin/res/sceditor/plugins/dragdrop.js
vendored
3
admin/res/sceditor/plugins/dragdrop.js
vendored
@ -1,3 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
||||
!function(n){"use strict";var v="data:image/gif;base64,R0lGODlhlgBkAPABAH19ffb29iH5BAAKAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAlgBkAAAC1YyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5LL5jE6r1+y2+w2Py+f0uv2OvwD2fP6iD/gH6Pc2GIhg2JeQSNjGuLf4GMlYKIloefAIUEl52ZmJyaY5mUhqyFnqmQr6KRoaMKp66hbLumpQ69oK+5qrOyg4a6qYV2x8jJysvMzc7PwMHS09TV1tfY2drb3N3e39DR4uPk5ebn6Onq6+zt7u/g4fL99UAAAh+QQACgAAACwAAAAAlgBkAIEAAAB9fX329vYAAAAC3JSPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5LL5jE6r1+y2+w2Py+f0uv2OvwD2fP4iABgY+CcoCNeHuJdQyLjIaOiWiOj4CEhZ+SbZd/nI2RipqYhQOThKGpAZCuBZyArZprpqSupaCqtaazmLCRqai7rb2av5W5wqSShcm8fc7PwMHS09TV1tfY2drb3N3e39DR4uPk5ebn6Onq6+zt7u/g4fLz9PX29/j5/vVAAAIfkEAAoAAAAsAAAAAJYAZACBAAAAfX199vb2AAAAAuCUj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/4PDAqHxKLxiEwql8ym8wmNSqfUqvWKzWq33K73Cw6Lx+Sy+YxOq9fstvsNj8vn9Lr9jr8E9nz+AgAYGLjQVwhXiJgguAiYgGjo9tinyCjoKLn3hpmJUGmJsBmguUnpCXCJOZraaXoKShoJe9DqehCqKlnqiZobuzrbyvuIO8xqKpxIPKlwrPCbBx0tPU1dbX2Nna29zd3t/Q0eLj5OXm5+jp6uvs7e7v4OHy8/T19vf4+fr7/P379UAAAh+QQACgAAACwAAAAAlgBkAIEAAAB9fX329vYAAAAC4JSPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5LL5jE6r1+y2+w2Py+f0uv2OvwT2fP6iD7gAMEhICAeImIAYiFDoOPi22KcouZfw6BhZGUBZeYlp6LbJiTD6CQqg6Vm6eQqqKtkZ24iaKtrKunpQa9tmmju7Wwu7KFtMi3oYDMzompkHHS09TV1tfY2drb3N3e39DR4uPk5ebn6Onq6+zt7u/g4fLz9PX29/j5+vv8/f31QAADs=",c=void 0!==window.FileReader,u=/data:[^;]+;base64,/i;function g(e){for(var t=e.substr(5,e.indexOf(";")-5),n=atob(e.substr(e.indexOf(",")+1)),r=new Uint8Array(n.length),i=0;i<n.length;i++)r[i]=n[i].charCodeAt(0);try{return new Blob([r],{type:t})}catch(e){return null}}n.plugins.dragdrop=function(){if(c){var A,r,o,i,a,s=0;this.signalReady=function(){A=(r=this).opts.dragdrop||{},o=A.handleFile,i=r.getContentAreaContainer().parentNode,a=i.appendChild(n.dom.parseHTML('<div class="sceditor-dnd-cover" style="display: none"><p>'+r._("Drop files here")+"</p></div>").firstChild),i.addEventListener("dragover",e),i.addEventListener("dragleave",d),i.addEventListener("dragend",d),i.addEventListener("drop",t),r.getBody().addEventListener("dragover",e),r.getBody().addEventListener("drop",d)},this.signalPasteHtml=function(e){if(!("handlePaste"in A)||A.handlePaste){var t=document.createElement("div");t.innerHTML=e.val;for(var n=t.querySelectorAll("img"),r=0;r<n.length;r++){var i=n[r];if(u.test(i.src)){var a=g(i.src);a&&l(a)?o(a,f(i)):i.parentNode.removeChild(i)}}e.val=t.innerHTML}}}function d(){a.style.display="none",i.className=i.className.replace(/(^| )dnd( |$)/g,"")}function l(e){return!("application/x-moz-file"!==e.type&&A.allowedTypes&&A.allowedTypes.indexOf(e.type)<0)&&(!A.isAllowed||A.isAllowed(e))}function f(e){var n=document.createElement("img");function t(e){var t=r.getBody().ownerDocument.getElementById(n.id);t&&("string"==typeof e&&t.insertAdjacentHTML("afterend",e),t.parentNode.removeChild(t))}return n.src=v,n.className="sceditor-ignore",n.id="sce-dragdrop-"+s++,function(){return e?e.parentNode.replaceChild(n,e):r.wysiwygEditorInsertHtml(n.outerHTML),{insert:function(e){t(e)},cancel:t}}}function e(e){for(var t=e.dataTransfer,n=t.files.length||!t.items?t.files:t.items,r=0;r<n.length;r++)if("string"===n[r].kind)return;"none"===a.style.display&&(a.style.display="block",i.className+=" dnd"),e.preventDefault()}function t(e){var t=e.dataTransfer,n=t.files.length||!t.items?t.files:t.items;d();for(var r=0;r<n.length;r++){if("string"===n[r].kind)return;l(n[r])&&o(n[r],f())}e.preventDefault()}}}(sceditor);
|
35
admin/res/sceditor/plugins/flatPressFileManager.js
Normal file
35
admin/res/sceditor/plugins/flatPressFileManager.js
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* SCEditor FlatPress File Manager
|
||||
* http://www.flatpress.org
|
||||
*
|
||||
* Copyright (C) 2020, Francisco Arocas (franciscoarocas.com)
|
||||
*
|
||||
* SCEditor is licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* @author Francisco Arocas
|
||||
*/
|
||||
|
||||
// After load the plugin, we add first the editor icon
|
||||
sceditor.command.set('flatPressFileManager', {
|
||||
exec: function() {
|
||||
/*
|
||||
An a open bootstrap modal function
|
||||
The modal html is in the .tpl file, where sceditor is included
|
||||
*/
|
||||
$('#flatpress-files-modal').modal('show');
|
||||
},
|
||||
tooltip: 'Open FlatPress File Manager'
|
||||
});
|
||||
|
||||
(function (sceditor) {
|
||||
'use strict';
|
||||
|
||||
var extend = sceditor.utils.extend;
|
||||
|
||||
sceditor.plugins.flatPressFileManager = function () {
|
||||
|
||||
this.init = function () { };
|
||||
|
||||
};
|
||||
}(sceditor));
|
@ -1,3 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
||||
!function(i){"use strict";i.plugins.format=function(){var n,a,c={p:"Paragraph",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6",address:"Address",pre:"Preformatted Text"};this.init=function(){var e=this.opts,t=e.paragraphformat;e.format&&"bbcode"===e.format||(t&&(t.tags&&(c=t.tags),t.excludeTags&&t.excludeTags.forEach(function(e){delete c[e]})),this.commands.format||(this.commands.format={exec:a,txtExec:a,tooltip:"Format Paragraph"}),e.toolbar===i.defaultOptions.toolbar&&(e.toolbar=e.toolbar.replace(",color,",",color,format,")))},n=function(e,t){e.sourceMode()?e.insert("<"+t+">","</"+t+">"):e.execCommand("formatblock","<"+t+">")},a=function(e){var o=this,r=document.createElement("div");i.utils.each(c,function(t,a){var e=document.createElement("a");e.className="sceditor-option",e.textContent=a.name||a,e.addEventListener("click",function(e){o.closeDropDown(!0),a.exec?a.exec(o):n(o,t),e.preventDefault()}),r.appendChild(e)}),o.createDropDown(e,"format",r)}}}(sceditor);
|
@ -1,3 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
||||
!function(t){"use strict";var i=t.utils.extend;t.plugins.plaintext=function(){var e=!0;this.init=function(){var t=this.commands,n=this.opts;n&&n.plaintext&&n.plaintext.addButton&&(e=n.plaintext.enabled,t.pastetext=i(t.pastetext||{},{state:function(){return e?1:0},exec:function(){e=!e}}))},this.signalPasteRaw=function(t){if(e){if(t.html&&!t.text){var n=document.createElement("div");n.innerHTML=t.html,t.text=n.innerText}t.html=null}}}}(sceditor);
|
@ -1,2 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
@ -1,3 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
||||
!function(e){"use strict";sceditor.plugins.undo=function(){var r,o,e=this,u=0,a=50,n=[],c=[],s=!1,l=function(e){s=!0,o=e.value,r.sourceMode(e.sourceMode),r.val(e.value,!1),r.focus(),e.sourceMode?r.sourceEditorCaret(e.caret):r.getRangeHelper().restoreRange(),s=!1};e.init=function(){a=(r=this).undoLimit||a,r.addShortcut("ctrl+z",e.undo),r.addShortcut("ctrl+shift+z",e.redo),r.addShortcut("ctrl+y",e.redo)},e.undo=function(){var e=c.pop(),t=r.val(null,!1);return e&&!n.length&&t===e.value&&(e=c.pop()),e&&(n.length||n.push({caret:r.sourceEditorCaret(),sourceMode:r.sourceMode(),value:t}),n.push(e),l(e)),!1},e.redo=function(){var e=n.pop();return c.length||(c.push(e),e=n.pop()),e&&(c.push(e),l(e)),!1},e.signalReady=function(){var e=r.val(null,!1);o=e,c.push({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:e})},e.signalValuechangedEvent=function(e){var t=e.detail.rawValue;0<a&&c.length>a&&c.shift(),!s&&o&&o!==t&&(n.length=0,(u+=function(e,t){var r,o,u,a,n=e.length,c=t.length,s=Math.max(n,c);for(r=0;r<s&&e.charAt(r)===t.charAt(r);r++);for(u=n<c?c-n:0,a=c<n?n-c:0,o=s-1;0<=o&&e.charAt(o-u)===t.charAt(o-a);o--);return o-r+1}(o,t))<20||u<50&&!/\s$/g.test(e.rawValue)||(c.push({caret:r.sourceEditorCaret(),sourceMode:r.sourceMode(),value:t}),u=0,o=t))}}}();
|
@ -1,3 +0,0 @@
|
||||
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
|
||||
|
||||
!function(t,r){"use strict";var e=t.plugins;function n(c){if(c._scePatched)return c;var t=function(){for(var t=[],e=0;e<arguments.length;e++){var n=arguments[e];n&&n.nodeType?t.push(r(n)):t.push(n)}return c.apply(this,t)};return t._scePatched=!0,t}function c(t){if(t._scePatched)return t;var e=function(){return r(t.apply(this,arguments))};return e._scePatched=!0,e}var o=t.command.set;if(t.command.set=function(t,e){return e&&"function"==typeof e.exec&&(e.exec=n(e.exec)),e&&"function"==typeof e.txtExec&&(e.txtExec=n(e.txtExec)),o.call(this,t,e)},e.bbcode){var a=e.bbcode.bbcode.set;e.bbcode.bbcode.set=function(t,e){return e&&"function"==typeof e.format&&(e.format=n(e.format)),a.call(this,t,e)}}var i=t.create;t.create=function(t,e){if(i.call(this,t,e),t&&t._sceditor){var n=t._sceditor;n.getBody=c(n.getBody),n.getContentAreaContainer=c(n.getContentAreaContainer)}}}(sceditor,jQuery);
|
94
ajax.php
Normal file
94
ajax.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/*
|
||||
Flatpress Ajax
|
||||
It recives OP and arguments, and return the result
|
||||
Created by Francisco Arocas
|
||||
Website: franciscoarocas.com
|
||||
*/
|
||||
|
||||
require_once ('defaults.php');
|
||||
require_once (INCLUDES_DIR.'includes.php');
|
||||
system_init();
|
||||
|
||||
// It contents all Operations and code
|
||||
$ajaxFunctions = [];
|
||||
|
||||
// It contents if Operation is and admin operation or not
|
||||
// If is and admin, user need to be logged
|
||||
// True if needs admin, false if not
|
||||
$ajaxIsAdminOrNot = [];
|
||||
|
||||
/* Functions to add Flarpress Ajax operations */
|
||||
|
||||
function addAjaxOperation($operationName, $isAdminOrNot, $operationFunction) {
|
||||
global $ajaxFunctions, $ajaxIsAdminOrNot;
|
||||
if(array_key_exists($operationName, $ajaxFunctions)) {
|
||||
throw new Exception('Error, AjaxOperationName exists.');
|
||||
}
|
||||
|
||||
$ajaxFunctions[$operationName] = $operationFunction;
|
||||
$ajaxIsAdminOrNot[$operationName] = $isAdminOrNot;
|
||||
}
|
||||
|
||||
function addAdminAjaxOperation($operationName, $operationFunction) {
|
||||
addAjaxOperation($operationName, true, $operationFunction);
|
||||
}
|
||||
|
||||
function addAdminNoAjaxOperation($operationName, $operationFunction) {
|
||||
addAjaxOperation($operationName, false, $operationFunction);
|
||||
}
|
||||
|
||||
define('AJAXERROR', false);
|
||||
define('AJAXSUCCESS', true);
|
||||
|
||||
function returnJSONValue($resultValue, $resultContent) {
|
||||
$Value = new stdClass;
|
||||
$Value->result = $resultValue;
|
||||
$Value->content = $resultContent;
|
||||
echo json_encode($Value);
|
||||
die();
|
||||
}
|
||||
|
||||
/* Include all Admin Ajax operations */
|
||||
|
||||
require_once(ADMIN_DIR . 'adminAjaxOperations.php');
|
||||
|
||||
foreach($AjaxFunctionMap as $currentName => $currentFunction) {
|
||||
addAdminAjaxOperation($currentName, $currentFunction);
|
||||
}
|
||||
|
||||
/* Recibe $POST to access ajax Function */
|
||||
|
||||
$_POST['Operation'] = 'Hello World'; // Test
|
||||
$_POST['Arguments'] = 'BLa bLa bLa'; // Test
|
||||
|
||||
if(isset($_POST)) {
|
||||
|
||||
if(!isset($_POST['Operation'])) {
|
||||
returnJSONValue(AJAXERROR, 'Flatpress Ajax needs operation');
|
||||
}
|
||||
|
||||
if(!array_key_exists($_POST['Operation'], $ajaxFunctions)) {
|
||||
returnJSONValue(AJAXERROR, 'Flatpress Ajax Operation doesnt not exist');
|
||||
}
|
||||
|
||||
//Check if this OP needs admin permissions. If true, check users permissions.
|
||||
if($ajaxIsAdminOrNot[$_POST['Operation']]) {
|
||||
if(!user_loggedin()) {
|
||||
returnJSONValue(AJAXERROR, 'Forbidden. You dont have admin permissions');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if(!isset($_POST['Arguments'])) {
|
||||
$result = $ajaxFunctions[$_POST['Operation']]();
|
||||
} else {
|
||||
$result = $ajaxFunctions[$_POST['Operation']]($_POST['Arguments']);
|
||||
}
|
||||
returnJSONValue(AJAXSUCCESS, $result);
|
||||
} catch(Exception $e) {
|
||||
returnJSONValue(AJAXERROR, $e->getMessage());
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user