dynamic forum
This commit is contained in:
parent
5f9e78cf4a
commit
d306f2f57d
5 changed files with 122 additions and 101 deletions
|
@ -134,27 +134,25 @@ class PostController extends Controller
|
|||
|| $titleTooLong
|
||||
|| $textTooShort
|
||||
|| $textTooLong) {
|
||||
$message = "";
|
||||
$error = "";
|
||||
|
||||
if ($titleTooShort) {
|
||||
$message = "This title is too short!";
|
||||
$error = "This title is too short!";
|
||||
} elseif ($titleTooLong) {
|
||||
$message = "This title is too long!";
|
||||
$error = "This title is too long!";
|
||||
} elseif ($textTooShort) {
|
||||
$message = "Please make your post a little bit longer!";
|
||||
$error = "Please make your post a little bit longer!";
|
||||
} elseif ($textTooLong) {
|
||||
$message = "Your post is too long, you're gonna have to cut a little!";
|
||||
$error = "Your post is too long, you're gonna have to cut a little!";
|
||||
}
|
||||
|
||||
$redirect = route('forums.post', $post->id);
|
||||
|
||||
if (!isset($_SESSION['replyText'])) {
|
||||
$_SESSION['replyText'] = [];
|
||||
}
|
||||
|
||||
$_SESSION['replyText']["t{$forum->id}"] = $text;
|
||||
|
||||
return view('global/information', compact('message', 'redirect'));
|
||||
return $this->json(compact('error'));
|
||||
}
|
||||
|
||||
unset($_SESSION['replyText']["t{$forum->id}"]);
|
||||
|
@ -174,9 +172,11 @@ class PostController extends Controller
|
|||
$post->editUser = CurrentSession::$user;
|
||||
$post = $post->update();
|
||||
|
||||
$postLink = route('forums.post', $post->id);
|
||||
|
||||
return redirect($postLink);
|
||||
return $this->json([
|
||||
'id' => $post->id,
|
||||
'title' => $post->subject,
|
||||
'text' => $post->parsed,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -201,65 +201,41 @@ class TopicController extends Controller
|
|||
{
|
||||
$text = $_POST['text'] ?? null;
|
||||
|
||||
// Attempt to get the forum
|
||||
$topic = new Topic($id);
|
||||
|
||||
// And attempt to get the forum
|
||||
$forum = new Forum($topic->forum);
|
||||
|
||||
// Check if the topic exists
|
||||
if ($topic->id === 0
|
||||
if (!session_check()
|
||||
|| $topic->id === 0
|
||||
|| $forum->type !== 0
|
||||
|| !$forum->perms->view) {
|
||||
$message = "This post doesn't exist or you don't have access to it!";
|
||||
$redirect = route('forums.index');
|
||||
|
||||
return view('global/information', compact('message', 'redirect'));
|
||||
return $this->json(['error' => "This post doesn't exist or you don't have access to it!"]);
|
||||
}
|
||||
|
||||
// Check if the topic exists
|
||||
if (!$forum->perms->reply
|
||||
|| (
|
||||
$topic->status === 1
|
||||
&& !$forum->perms->changeStatus
|
||||
)) {
|
||||
$message = "You are not allowed to post in this topic!";
|
||||
$redirect = route('forums.topic', $topic->id);
|
||||
|
||||
return view('global/information', compact('message', 'redirect'));
|
||||
return $this->json(['error' => "You are not allowed to post in this topic!"]);
|
||||
}
|
||||
|
||||
// Length
|
||||
$length = strlen($text);
|
||||
$minLen = config('forum.min_post_length');
|
||||
$maxLen = config('forum.max_post_length');
|
||||
$tooShort = $length < $minLen;
|
||||
$tooLong = $length > $maxLen;
|
||||
|
||||
// Check requirments
|
||||
if ($tooShort
|
||||
|| $tooLong) {
|
||||
$route = route('forums.topic', $topic->id);
|
||||
|
||||
$message = "Your post is " . (
|
||||
$tooShort
|
||||
? "too short, add some more text! Make it at least {$minLen}."
|
||||
: "too long, you're gonna have to cut a little! Keep it under {$maxLen}."
|
||||
);
|
||||
$redirect = "{$route}#reply";
|
||||
|
||||
if (!isset($_SESSION['replyText'])) {
|
||||
$_SESSION['replyText'] = [];
|
||||
}
|
||||
|
||||
$_SESSION['replyText']["t{$topic->id}"] = $text;
|
||||
|
||||
return view('global/information', compact('message', 'redirect'));
|
||||
return $this->json([
|
||||
'error' => "Your post is " . (
|
||||
$tooShort
|
||||
? "too short, add some more text! Make it at least {$minLen}."
|
||||
: "too long, you're gonna have to cut a little! Keep it under {$maxLen}."
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
unset($_SESSION['replyText']["t{$topic->id}"]);
|
||||
|
||||
// Create the post
|
||||
$post = Post::create(
|
||||
"Re: {$topic->title}",
|
||||
$text,
|
||||
|
@ -268,16 +244,13 @@ class TopicController extends Controller
|
|||
$forum->id
|
||||
);
|
||||
|
||||
// Go to the post
|
||||
$postLink = route('forums.post', $post->id);
|
||||
|
||||
// Head to the post
|
||||
return redirect($postLink);
|
||||
return $this->json(['error' => null, 'go' => route('forums.post', $post->id)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a topic.
|
||||
* @param int $id
|
||||
* @throws HttpMethodNotAllowedException
|
||||
* @return string
|
||||
*/
|
||||
public function create(int $id = 0): string
|
||||
|
@ -294,14 +267,18 @@ class TopicController extends Controller
|
|||
|| !$forum->perms->view
|
||||
|| !$forum->perms->reply
|
||||
|| !$forum->perms->topicCreate) {
|
||||
$message = "This forum doesn't exist or you don't have access to it!";
|
||||
$redirect = route('forums.index');
|
||||
|
||||
return view('global/information', compact('message', 'redirect'));
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
return $this->json(['error' => "This forum doesn't exist or you don't have access to it!"]);
|
||||
} else {
|
||||
throw new HttpMethodNotAllowedException;
|
||||
}
|
||||
}
|
||||
|
||||
if ($text && $title) {
|
||||
// Length
|
||||
if ($text !== null && $title !== null) {
|
||||
if (!session_check()) {
|
||||
return $this->json(['error' => 'Your session expired, please refresh!']);
|
||||
}
|
||||
|
||||
$titleLength = strlen($title);
|
||||
$textLength = strlen($text);
|
||||
$titleMin = config('forum.min_title_length');
|
||||
|
@ -309,45 +286,33 @@ class TopicController extends Controller
|
|||
$textMin = config('forum.min_post_length');
|
||||
$textMax = config('forum.max_post_length');
|
||||
|
||||
// Checks
|
||||
$titleTooShort = $titleLength < $titleMin;
|
||||
$titleTooLong = $titleLength > $titleMax;
|
||||
$textTooShort = $textLength < $textMin;
|
||||
$textTooLong = $textLength > $textMax;
|
||||
|
||||
// Check requirments
|
||||
if ($titleTooShort
|
||||
|| $titleTooLong
|
||||
|| $textTooShort
|
||||
|| $textTooLong) {
|
||||
$message = "";
|
||||
$error = "";
|
||||
|
||||
if ($titleTooShort) {
|
||||
$message = "This title is too short, it has to be longer than {$titleMin} characters!";
|
||||
$error = "This title is too short, it has to be longer than {$titleMin} characters!";
|
||||
} elseif ($titleTooLong) {
|
||||
$message = "This title is too long, keep it under {$titleMax} characters!";
|
||||
$error = "This title is too long, keep it under {$titleMax} characters!";
|
||||
} elseif ($textTooShort) {
|
||||
$message = "Please make your post a little bit longer, at least {$textMin} characters!";
|
||||
$error = "Please make your post a little bit longer, at least {$textMin} characters!";
|
||||
} elseif ($textTooLong) {
|
||||
$message = "Your post is too long, you're gonna have to cut a little!"
|
||||
$error = "Your post is too long, you're gonna have to cut a little!"
|
||||
. " Can't be more than {$textMax} characters.";
|
||||
}
|
||||
|
||||
$redirect = route('forums.new', $forum->id);
|
||||
|
||||
if (!isset($_SESSION['replyText'])) {
|
||||
$_SESSION['replyText'] = [];
|
||||
}
|
||||
|
||||
$_SESSION['replyText']["f{$forum->id}"]["title"] = $title;
|
||||
$_SESSION['replyText']["f{$forum->id}"]["text"] = $text;
|
||||
|
||||
return view('global/information', compact('message', 'redirect'));
|
||||
return $this->json(compact('error'));
|
||||
}
|
||||
|
||||
unset($_SESSION['replyText']["f{$forum->id}"]);
|
||||
|
||||
// Create the post
|
||||
$post = Post::create(
|
||||
$title,
|
||||
$text,
|
||||
|
@ -356,11 +321,7 @@ class TopicController extends Controller
|
|||
$forum->id
|
||||
);
|
||||
|
||||
// Go to the post
|
||||
$postLink = route('forums.post', $post->id);
|
||||
|
||||
// Head to the post
|
||||
return redirect($postLink);
|
||||
return $this->json(['error' => null, 'go' => route('forums.post', $post->id)]);
|
||||
}
|
||||
|
||||
return view('forum/topic', compact('forum'));
|
||||
|
|
|
@ -30,10 +30,6 @@
|
|||
height: 150px;
|
||||
margin: 5px auto;
|
||||
|
||||
&--online {
|
||||
box-shadow: 0 3px 7px #484;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
|
|
@ -14,12 +14,13 @@
|
|||
} %}
|
||||
|
||||
<div id="reply">
|
||||
<form id="postingForm" method="post" action="{{ postingAction }}">
|
||||
<div id="postingTitleContainer"{% if titleCache is not defined %} style="display: none;"{% endif %}>
|
||||
<input type="text" class="input__text" name="title" id="postingTitle" placeholder="Title" value="{{ titleCache is defined ? titleCache : '' }}">
|
||||
<form id="postingForm" method="post" action="javascript:void(0)" onsubmit="yuunoForumSubmit(this)">
|
||||
<input type="hidden" name="session" value="{{ session_id() }}">
|
||||
<div id="postingTitleContainer"{% if topic is defined %} style="display: none;"{% endif %}>
|
||||
<input type="text" class="input__text" name="title" id="postingTitle" placeholder="Title">
|
||||
</div>
|
||||
<div>
|
||||
<textarea class="input__text" name="text" id="postingText" placeholder="Hit ctrl+enter to submit quickly!"{% if titleCache is defined %} autofocus{% endif %}>{{ textCache }}</textarea>
|
||||
<textarea class="input__text" name="text" id="postingText" placeholder="Hit ctrl+enter to submit quickly!"></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
|
@ -58,7 +59,8 @@
|
|||
postFetch = new Sakura.AJAX(),
|
||||
parserActive = false,
|
||||
op = {{ topic is defined ? topic.firstPost.id : 0 }},
|
||||
topicName = "{{ topic is defined ? topic.firstPost.subject : '' }}";
|
||||
topicName = "{{ topic is defined ? topic.firstPost.subject : '' }}",
|
||||
editing = 0;
|
||||
|
||||
pText.addEventListener("focus", function () {
|
||||
preview.style.display = null;
|
||||
|
@ -79,7 +81,7 @@
|
|||
}
|
||||
|
||||
if (e.keyCode == 13 && e.ctrlKey) {
|
||||
pForm.submit();
|
||||
pForm.onsubmit();
|
||||
}
|
||||
|
||||
Sakura.Editor.PreviewTimeout(rText, pText);
|
||||
|
@ -113,6 +115,7 @@
|
|||
pText.disabled = true;
|
||||
pTitleCont.style.display = 'none';
|
||||
rTitle.innerText = 'Re: ' + topicName;
|
||||
editing = id;
|
||||
|
||||
url = "{{ route('forums.post.raw', '1') }}".replace('1', id);
|
||||
|
||||
|
@ -121,7 +124,7 @@
|
|||
postFetch.AddCallback(200, function () {
|
||||
pText.value = postFetch.Response();
|
||||
pStopEdit.style.display = null;
|
||||
pForm.action = "{{ route('forums.post.edit', '1') }}".replace('1', id);
|
||||
pForm.setAttribute('onsubmit', "editSave(this, " + id + ")");
|
||||
pMode.innerText = 'Editing #' + id;
|
||||
if (id === op) {
|
||||
pTitleCont.style.display = null;
|
||||
|
@ -135,12 +138,76 @@
|
|||
postFetch.Start(Sakura.HTTPMethod.GET);
|
||||
}
|
||||
|
||||
function editSave(form, id) {
|
||||
var client = new Sakura.AJAX;
|
||||
client.SetUrl("{{ route('forums.post.edit', '1') }}".replace('1', id));
|
||||
client.SetFormData(new FormData(form));
|
||||
client.AddCallback(200, function () {
|
||||
var result = client.JSON();
|
||||
|
||||
if (result.error) {
|
||||
var error = new Sakura.Dialogue;
|
||||
error.Title = "Error";
|
||||
error.Text = result.error;
|
||||
error.SetType(Sakura.DialogueType.Info);
|
||||
|
||||
error.AddCallback(Sakura.DialogueButton.Ok, function () {
|
||||
this.Close();
|
||||
});
|
||||
|
||||
error.Display();
|
||||
} else {
|
||||
stopEdit();
|
||||
|
||||
if (result.id === op) {
|
||||
topicName = result.title;
|
||||
}
|
||||
|
||||
var post = Sakura.DOM.ID('p' + result.id);
|
||||
post.querySelector('.post__text').innerHTML = result.text;
|
||||
post.querySelector('.post__title').innerText = result.title.substring(0, 50) + (result.title.length > 50 ? '...' : '');
|
||||
post.scrollIntoView(true);
|
||||
}
|
||||
});
|
||||
client.Start(Sakura.HTTPMethod.POST);
|
||||
}
|
||||
|
||||
function stopEdit() {
|
||||
editing = 0;
|
||||
pText.value = "";
|
||||
pForm.action = "{{ postingAction }}";
|
||||
pStopEdit.style.display = 'none';
|
||||
pTitleCont.style.display = 'none';
|
||||
pMode.innerText = 'Preview';
|
||||
preview.style.display = 'none';
|
||||
}
|
||||
|
||||
function yuunoForumSubmit(form) {
|
||||
if (editing) {
|
||||
editSave(form, editing);
|
||||
return;
|
||||
}
|
||||
|
||||
var client = new Sakura.AJAX;
|
||||
client.SetUrl("{{ postingAction }}");
|
||||
client.SetFormData(new FormData(form));
|
||||
client.AddCallback(200, function () {
|
||||
var result = client.JSON();
|
||||
|
||||
if (result.error) {
|
||||
var error = new Sakura.Dialogue;
|
||||
error.Title = "Error";
|
||||
error.Text = result.error;
|
||||
error.SetType(Sakura.DialogueType.Info);
|
||||
|
||||
error.AddCallback(Sakura.DialogueButton.Ok, function () {
|
||||
this.Close();
|
||||
});
|
||||
|
||||
error.Display();
|
||||
} else if (result.go) {
|
||||
window.location.assign(result.go)
|
||||
}
|
||||
});
|
||||
client.Start(Sakura.HTTPMethod.POST);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -98,7 +98,6 @@
|
|||
|
||||
{% if topic is defined %}
|
||||
|
||||
{% set textCache = session.replyText['t' ~ topic.id]|default(null) %}
|
||||
{% set postingAction = route('forums.topic.reply', topic.id) %}
|
||||
|
||||
{% for post in posts[get.page|default(1) - 1] %}
|
||||
|
@ -109,12 +108,12 @@
|
|||
<a class="post__username" href="{{ route('user.profile', post.poster.id) }}" style="color: {{ post.poster.colour }}; text-shadow: 0 0 5px {% if post.poster.colour != 'inherit' %}{{ post.poster.colour }}{% else %}#222{% endif %}">
|
||||
{{ post.poster.username }}
|
||||
</a>
|
||||
<div class="avatar avatar--border post__avatar{% if post.poster.isOnline %} post__avatar--online{% endif %}" style="background-image: url('{{ route('user.avatar', post.poster.id) }}')"></div>
|
||||
<div class="avatar avatar--border post__avatar" style="background-image: url('{{ route('user.avatar', post.poster.id) }}')"></div>
|
||||
|
||||
<div class="post__usertitle">{{ post.poster.title }}</div>
|
||||
|
||||
<img src="/images/tenshi.png" alt="Tenshi"{% if not post.poster.isPremium %} style="opacity: 0;"{% endif %}>
|
||||
<img src="/images/flags/{{ post.poster.country|lower }}.png" alt="{{ post.poster.country(true) }}">
|
||||
<img src="/images/flags/{{ post.poster.country|lower }}.png" alt="{{ post.poster.country }}" title="{{ post.poster.country(true) }}">
|
||||
|
||||
{% if post.poster.id == (topic.posts|first).poster.id %}
|
||||
<img src="/images/op.png" alt="OP" title="Original Poster">
|
||||
|
@ -168,25 +167,23 @@
|
|||
|
||||
{% else %}
|
||||
|
||||
{% set titleCache = session.replyText['f' ~ forum.id].title|default('') %}
|
||||
{% set textCache = session.replyText['f' ~ forum.id].text|default('') %}
|
||||
{% set postingAction = route('forums.new', forum.id) %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if forumReplyLink is defined or topic is not defined %}
|
||||
<div class="post" id="postingPreview" style="display: none">
|
||||
<div class="post" id="postingPreview"{% if topic is defined %} style="display: none;"{% endif %}>
|
||||
<div class="post__details">
|
||||
<div class="post__user">
|
||||
<a class="post__username" href="{{ route('user.profile', user.id) }}" style="color: {{ user.colour }}; text-shadow: 0 0 5px {% if user.colour != 'inherit' %}{{ user.colour }}{% else %}#222{% endif %}">
|
||||
{{ user.username }}
|
||||
</a>
|
||||
<div class="avatar avatar--border post__avatar post__avatar--online" style="background-image: url('{{ route('user.avatar', user.id) }}')"></div>
|
||||
<div class="avatar avatar--border post__avatar" style="background-image: url('{{ route('user.avatar', user.id) }}')"></div>
|
||||
|
||||
<div class="post__usertitle">{{ user.title }}</div>
|
||||
|
||||
<img src="/images/tenshi.png" alt="Tenshi"{% if not user.isPremium %} style="opacity: 0;"{% endif %}>
|
||||
<img src="/images/flags/{{ user.country|lower }}.png" alt="{{ user.country(true) }}">
|
||||
<img src="/images/flags/{{ user.country|lower }}.png" alt="{{ user.country }}" title="{{ user.country(true) }}">
|
||||
|
||||
{% if not topic is defined %}
|
||||
<img src="/images/op.png" alt="OP" title="Original Poster">
|
||||
|
@ -196,7 +193,7 @@
|
|||
<div class="post__contents">
|
||||
<div class="post__info">
|
||||
<span id="previewTitle" class="post__title">
|
||||
{% if not titleCache is defined %}Re: {{ topic.title }}{% endif %}
|
||||
{% if topic is defined %}Re: {{ topic.title }}{% endif %}
|
||||
</span>
|
||||
<span id="previewMode" class="post__date">
|
||||
Preview
|
||||
|
|
Reference in a new issue