Skip to content

Commit

Permalink
Correct post history logs
Browse files Browse the repository at this point in the history
  • Loading branch information
danon committed Dec 6, 2023
1 parent 55c0353 commit 8079235
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 128 deletions.
56 changes: 43 additions & 13 deletions app/Http/Controllers/Forum/LogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,57 @@

use Coyote\Post;
use Coyote\Services\UrlBuilder;
use Illuminate\Database\Eloquent;
use Illuminate\View\View;

class LogController extends BaseController
{
public function log(Post $post): View
public function log(int $postId): View
{
$this->authorize('update', $post->topic->forum);
$this->breadcrumb($post->topic->forum);
$post = $this->postById($postId);
if ($post === null) {
abort(404);
}
$topic = $post->topic;
$forum = $topic->forum;
$this->authorize('update', $forum);
$this->breadcrumb($forum);
$this->breadcrumb->push([
$post->topic->title => UrlBuilder::topic($post->topic),
'Historia posta' => route('forum.post.log', [$post->id]),
$topic->title => UrlBuilder::topic($topic),
'Historia posta' => route('forum.post.log', [$post->id]),
]);
$logs = $this->post->history($post->id)->map(function (Post\Log $log): Post\Log {
$log->text = \htmlEntities($log->text);
return $log;
});
return $this->view('forum.log')->with([
'logs' => $logs,
'post' => $post,
'forum' => $post->topic->forum,
'topic' => $post->topic,
'logs' => $this->postLogs($post->id),
'post' => $post,
'forum' => $forum,
'topic' => $topic,
'topicLink' => route('forum.topic', [$forum->slug, $topic->id, $topic->slug]) . '?p=' . $post->id . '#id' . $post->id,
]);
}

private function postById(int $id): ?Post
{
$post = Post::withTrashed()->find($id);
if ($post === null) {
return null;
}
if ($post->deleted_at === null) {
return $post;
}
if ($this->getGateFactory()->allows('delete', $post->topic->forum)) {
return $post;
}
return null;
}

public function postLogs(int $postId): Eloquent\Collection
{
return Post\Log::query()
->select(['post_log.id', 'post_log.*'])
->where('post_id', $postId)
->join('posts', 'posts.id', '=', 'post_id')
->orderBy('post_log.id', 'DESC')
->with('user')
->get();
}
}
6 changes: 0 additions & 6 deletions app/Repositories/Contracts/PostRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ public function getFirstUnreadPostId($topicId, $markTime);
*/
public function merge($userId, $post);

/**
* @param int $postId
* @return mixed
*/
public function history(int $postId);

/**
* @param int $userId
* @return mixed
Expand Down
18 changes: 1 addition & 17 deletions app/Repositories/Eloquent/PostRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public function lengthAwarePagination(Topic $topic, int $page = 0, int $perPage
*/
public function getPage($postId, $topicId, $perPage = 10)
{
/** @var int $count */
$count = $this->applyCriteria(function () use ($topicId, $postId) {
return $this
->model
Expand Down Expand Up @@ -147,23 +148,6 @@ public function merge($userId, $post)
return $previous;
}

/**
* @param int $postId
* @return mixed
*/
public function history(int $postId)
{
return Post\Log::select([
'post_log.id',
'post_log.*'
])
->where('post_id', $postId)
->join('posts', 'posts.id', '=', 'post_id')
->orderBy('post_log.id', 'DESC')
->with('user')
->get();
}

/**
* @param int $userId
* @return mixed
Expand Down
146 changes: 74 additions & 72 deletions resources/js/components/forum/post-log.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

<div class="col-10">
<i class="far fa-file"></i>

<a :href="`#id${log.id}`">{{ log.title }}</a>
<a :href="`#id${log.id}`">
{{ log.title }}
</a>
</div>
</div>
</div>
Expand All @@ -23,14 +24,14 @@
<ul class="post-stats list-unstyled">
<li>
<strong>Data:</strong>
<small><vue-timeago :datetime="log.created_at"></vue-timeago></small>
<small>
<vue-timeago :datetime="log.created_at"/>
</small>
</li>

<li>
<strong>IP:</strong>
<small>{{ log.ip }}</small>
</li>

<li class="text-truncate">
<strong>Przeglądarka:</strong>
<small :title="log.browser">{{ log.browser }}</small>
Expand All @@ -39,15 +40,7 @@
</div>

<div class="col-12 col-lg-10 diff">
<div v-if="isLoaded" class="post-content" v-html="diffStr"></div>

<!-- {% if log.tags %}-->
<!-- <ul class="tag-clouds">-->
<!-- {% for tag in log.tags %}-->
<!-- <li><a href="{{ route('forum.tag', [tag|url_encode]) }}">{{ tag }}</a></li>-->
<!-- {% endfor %}-->
<!-- </ul>-->
<!-- {% endif %}-->
<div v-if="isLoaded" class="post-content" v-html="diffStr" style="white-space: pre-wrap"/>
</div>
</div>
</div>
Expand All @@ -56,80 +49,89 @@
<div class="row">
<div class="d-none d-lg-block col-lg-2"></div>
<div class="col-12 d-flex col-lg-10">

<a v-if="isRollbackEnabled" @click="rollback" title="Cofnij do tej wersji" class="btn btn-sm btn-rollback">
<i class="fas fa-undo"></i>

<i class="fas fa-undo"/>
Cofnij do tej wersji
</a>
<a v-else class="btn btn-sm" :href="this.topicLink">
<i class="fas fa-eye"/>
Pokaż aktualną wersję
</a>
</div>
</div>
</div>
</section>
</template>

<script lang="ts">
import Vue from 'vue';
import { Prop } from "vue-property-decorator";
import { PostLog } from "@/types/models";
import Component from "vue-class-component";
import VueUserName from "@/components/user-name.vue";
import VueModal from "@/components/delete-modal.vue";
@Component({
components: { 'vue-username': VueUserName, 'vue-modal': VueModal }
})
export default class VuePostLog extends Vue {
@Prop()
readonly log!: PostLog;
@Prop()
readonly isRollbackEnabled!: boolean;
@Prop({default: null})
readonly oldStr!: string | null;
isLoaded = false;
private diff: any;
created() {
return import('diff').then((Diff) => {
this.diff = Diff;
this.isLoaded = true;
});
}
import Vue from 'vue';
import {Prop} from "vue-property-decorator";
import {PostLog} from "@/types/models";
import Component from "vue-class-component";
import VueUserName from "@/components/user-name.vue";
import VueModal from "@/components/delete-modal.vue";
@Component({
components: {'vue-username': VueUserName, 'vue-modal': VueModal}
})
export default class VuePostLog extends Vue {
@Prop()
readonly log!: PostLog;
@Prop()
readonly topicLink!: string;
@Prop()
readonly isRollbackEnabled!: boolean;
@Prop({default: null})
readonly oldStr!: string | null;
isLoaded = false;
private diff: any;
created() {
return import('diff').then((diff) => {
this.diff = diff;
this.isLoaded = true;
});
}
async rollback() {
await this.$confirm({
message: 'Treść posta zostanie zastąpiona. Czy chcesz kontynuować?',
title: 'Potwierdź operację',
okLabel: 'Tak, przywróć'
});
async rollback() {
await this.$confirm({
message: 'Treść posta zostanie zastąpiona. Czy chcesz kontynuować?',
title: 'Potwierdź operację',
okLabel: 'Tak, przywróć'
});
const {data} = await this.$store.dispatch('posts/rollback', this.log);
const { data } = await this.$store.dispatch('posts/rollback', this.log);
window.location.href = data.url;
}
window.location.href = data.url;
get diffStr() {
if (!this.oldStr) {
return this.log.text;
}
const diff = this.diff.diffWords(
encodeHtml(this.oldStr),
encodeHtml(this.log.text));
get diffStr() {
if (!this.oldStr) {
return this.log.text;
return diff.reduce((acc: string, part): string => {
if (part.added) {
return acc + `<ins class="text-primary">${part.value}</ins>`;
}
if (part.removed) {
return acc + `<del class="text-danger">${part.value}</del>`;
}
return acc + part.value;
}, '');
}
}
const diff = this.diff.diffChars(this.oldStr, this.log.text);
let diffStr = '';
diff.forEach(part => {
if (part.added) {
diffStr += `<ins class="text-primary">${part.value}</ins>`;
} else if (part.removed) {
diffStr += `<del class="text-danger">${part.value}</del>`;
} else {
diffStr += part.value;
}
});
const tmp = document.createElement("div");
return diffStr.replace("\n", "<br>");
}
}
function encodeHtml(text: string): string {
tmp.innerText = text;
return tmp.innerHTML;
}
</script>
1 change: 1 addition & 0 deletions resources/js/pages/forum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ declare global {
topics: Models.Paginator;
popularTags: string[];
logs: Models.PostLog[];
topicLink: string;
}
}

Expand Down
10 changes: 7 additions & 3 deletions resources/js/pages/forum/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import store from '@/store';

export default Vue.extend({
delimiters: ['${', '}'],
components: { 'vue-log': VuePostLog },
components: {'vue-log': VuePostLog},
store,
data: () => ({
logs: window.logs
logs: window.logs,
topicLink: window.topicLink,
}),
methods: {
oldStr(logs, index) {
return index == logs.length -1 ? null : logs[index + 1].text;
if (index == logs.length - 1) {
return null;
}
return logs[index + 1].text;
}
}
});
26 changes: 10 additions & 16 deletions resources/views/forum/log.twig
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
{% extends 'forum.base' %}
{% block title %}Historia edycji posta w {{ topic.title }}{{ parent() }}{% endblock %}

{% import 'components.widgets' as widgets %}

{% set url = route('forum.post.log', [post.id]) %}

{% block content %}

{% include "forum.partials.top" %}

<h1>{{ link_to_route('forum.topic', topic.title, [forum.slug, topic.id, topic.slug]) }}</h1>

<h1>
{{ link_to_route('forum.topic', topic.title, [forum.slug, topic.id, topic.slug]) }}
</h1>
<main id="js-log" class="mainbar">
<vue-log
v-for="(log, index) in logs"
:log="log"
:key="log.id"
:is-rollback-enabled="index > 0"
:old-str="oldStr(logs, index)"
/>
v-for="(log, index) in logs"
:log="log"
:key="log.id"
:topic-link="topicLink"
:is-rollback-enabled="index > 0"
:old-str="oldStr(logs, index)"/>
</main>

<script>
var logs = {{ logs|json_encode|raw }};
var topicLink = {{ topicLink|json_encode|raw }};
</script>

{% endblock %}

2 changes: 1 addition & 1 deletion routes/forum.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
// akceptowanie danego posta jako poprawna odpowiedz w watku
$this->post('Post/Accept/{post}', ['uses' => 'AcceptController@index', 'as' => 'post.accept', 'middleware' => 'auth']);
// historia edycji danego posta
$this->get('Post/Log/{post}', ['uses' => 'LogController@log', 'as' => 'post.log']);
$this->get('Post/Log/{id}', ['uses' => 'LogController@log', 'as' => 'post.log']);
// przywrocenie poprzedniej wersji posta
$this->post('Post/Rollback/{post}/{id}', ['uses' => 'RollbackController@rollback', 'as' => 'post.rollback']);
// mergowanie posta z poprzednim
Expand Down

0 comments on commit 8079235

Please sign in to comment.