dynamic forum

This commit is contained in:
flash 2016-12-09 20:25:22 +01:00
parent 5f9e78cf4a
commit d306f2f57d
5 changed files with 122 additions and 101 deletions

View file

@ -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,
]);
}
/**

View file

@ -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'));

View file

@ -30,10 +30,6 @@
height: 150px;
margin: 5px auto;
&--online {
box-shadow: 0 3px 7px #484;
}
@media (max-width: 768px) {
width: 100px;
height: 100px;

View file

@ -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>

View file

@ -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