Skip to content

Commit

Permalink
feat: migrate User Recent Posts to React.js (#2664)
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Sep 8, 2024
1 parent 753173d commit c5a9891
Show file tree
Hide file tree
Showing 44 changed files with 507 additions and 492 deletions.
5 changes: 3 additions & 2 deletions app/Community/Components/UserProfileMeta.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use App\Platform\Enums\PlayerStatType;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\View\Component;

Expand Down Expand Up @@ -322,13 +323,13 @@ private function buildRankMetadata(
private function buildSocialStats(User $user): array
{
$userSetRequestInformation = getUserRequestsInformation($user);
$numForumPosts = $user->forumPosts()->count();
$numForumPosts = $user->forumPosts()->authorized()->viewable(Auth::user())->count();

// Forum posts
$forumPostsStat = [
'label' => 'Forum posts',
'value' => localized_number($numForumPosts),
'href' => $numForumPosts ? route('user.posts', ['user' => $user]) : null,
'href' => $numForumPosts ? route('user.posts.index', ['user' => $user]) : null,
'isMuted' => $numForumPosts === 0,
];

Expand Down
51 changes: 0 additions & 51 deletions app/Community/Controllers/ForumTopicCommentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,13 @@
use App\Community\Actions\AddCommentAction;
use App\Community\Actions\GetUrlToCommentDestinationAction;
use App\Community\Requests\ForumTopicCommentRequest;
use App\Community\Services\ForumRecentPostsPageService;
use App\Models\ForumTopic;
use App\Models\ForumTopicComment;
use App\Support\Shortcode\Shortcode;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Inertia\Inertia;
use Inertia\Response as InertiaResponse;

class ForumTopicCommentController extends CommentController
{
public function __construct(
protected ForumRecentPostsPageService $recentPostsPageService
) {
}

/**
* There is no create form for creating a new comment.
* comments have to be created for something -> use sub resource create route, e.g.
Expand Down Expand Up @@ -92,46 +83,4 @@ protected function destroy(ForumTopicComment $comment): RedirectResponse
return redirect($return)
->with('success', $this->resourceActionSuccessMessage('comment', 'delete'));
}

public function showRecentPosts(): InertiaResponse
{
$this->authorize('viewAny', ForumTopicComment::class);

// TODO after POC: thin this out
$pageProps = $this->recentPostsPageService->buildViewData(
request()->user(),
(int) request()->input('offset', 0)
);

// TODO after POC: migrate the query to Eloquent ORM and have it do these mappings automatically
$mappedRecentForumPosts = [];
foreach ($pageProps['recentForumPosts'] as &$recentForumPost) {
$mappedRecentForumPost = [];

$mappedRecentForumPost['forumTopicId'] = (int) $recentForumPost['ForumTopicID'];
$mappedRecentForumPost['forumTopicTitle'] = $recentForumPost['ForumTopicTitle'];
$mappedRecentForumPost['commentId'] = (int) $recentForumPost['CommentID'];
$mappedRecentForumPost['postedAt'] = $recentForumPost['PostedAt'];
$mappedRecentForumPost['authorDisplayName'] = $recentForumPost['Author'];
$mappedRecentForumPost['shortMessage'] = Shortcode::stripAndClamp($recentForumPost['ShortMsg'], 999);
$mappedRecentForumPost['commentIdDay'] = isset($recentForumPost['CommentID_1d']) ? (int) $recentForumPost['CommentID_1d'] : null;
$mappedRecentForumPost['commentCountDay'] = isset($recentForumPost['Count_1d']) ? (int) $recentForumPost['Count_1d'] : null;
$mappedRecentForumPost['commentIdWeek'] = isset($recentForumPost['CommentID_7d']) ? (int) $recentForumPost['CommentID_7d'] : null;
$mappedRecentForumPost['commentCountWeek'] = isset($recentForumPost['Count_7d']) ? (int) $recentForumPost['Count_7d'] : null;

$mappedRecentForumPosts[] = $mappedRecentForumPost;
}
unset($pageProps['recentForumPosts']);
$pageProps['recentForumPosts'] = $mappedRecentForumPosts;

// TODO after POC: remove this code
if (isset($pageProps['previousPageUrl'])) {
$pageProps['previousPageUrl'] = str_replace('recent-posts', 'recent-posts2', $pageProps['previousPageUrl']);
}
if (isset($pageProps['nextPageUrl'])) {
$pageProps['nextPageUrl'] = str_replace('recent-posts', 'recent-posts2', $pageProps['nextPageUrl']);
}

return Inertia::render('forums/recent-posts', $pageProps);
}
}
103 changes: 103 additions & 0 deletions app/Community/Controllers/UserForumTopicCommentController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

declare(strict_types=1);

namespace App\Community\Controllers;

use App\Community\Data\UserRecentPostsPagePropsData;
use App\Data\ForumTopicData;
use App\Data\PaginatedData;
use App\Data\UserData;
use App\Enums\Permissions;
use App\Http\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Inertia\Inertia;
use Inertia\Response as InertiaResponse;

class UserForumTopicCommentController extends Controller
{
public function index(Request $request, User $user): InertiaResponse
{
$this->authorize('view', $user);

$offset = $request->input('page', 1) - 1;
$count = 25;

/** @var User $me */
$me = auth()->user();
$permissions = Permissions::Unregistered;
if ($me) {
$permissions = (int) $me->getAttribute('Permissions');
}

$posts = $this->getUserPosts(
$user,
page: (int) $request->input('page', 1),
permissions: $permissions,
);

$transformedPosts = array_map(
fn ($post) => ForumTopicData::fromUserPost($post)->include('latestComment'),
$posts
);

$paginator = new LengthAwarePaginator(
items: $transformedPosts,
total: $user->forumPosts()->authorized()->viewable($me)->count(),
perPage: $count,
currentPage: $offset + 1,
options: [
'path' => $request->url(),
'query' => $request->query(),
]
);

$paginatedPosts = PaginatedData::fromLengthAwarePaginator($paginator);

$props = new UserRecentPostsPagePropsData(
UserData::fromUser($user),
$paginatedPosts
);

return Inertia::render('user/[user]/posts', $props);
}

private function getUserPosts(User $user, int $page = 1, int $permissions = Permissions::Unregistered): array
{
$count = 25;
$offset = ($page - 1) * $count;

$query = "
SELECT
ft.ID AS ForumTopicID,
ft.Title AS ForumTopicTitle,
f.ID AS ForumID,
f.Title AS ForumTitle,
lftc.ID AS CommentID,
lftc.DateCreated AS PostedAt,
lftc.author_id,
ua.User AS Author,
ua.display_name AS AuthorDisplayName,
LEFT(lftc.Payload, 260) AS ShortMsg,
LENGTH(lftc.Payload) > 260 AS IsTruncated
FROM ForumTopicComment AS lftc
INNER JOIN ForumTopic AS ft ON ft.ID = lftc.ForumTopicID
INNER JOIN Forum AS f ON f.ID = ft.ForumID
LEFT JOIN UserAccounts AS ua ON ua.ID = lftc.author_id
WHERE lftc.author_id = :author_id
AND lftc.Authorised = 1
AND ft.RequiredPermissions <= :permissions
AND ft.deleted_at IS NULL
ORDER BY lftc.DateCreated DESC
LIMIT :offset, :count";

return legacyDbFetchAll($query, [
'author_id' => $user->id,
'offset' => $offset,
'count' => $count,
'permissions' => $permissions,
])->toArray();
}
}
20 changes: 20 additions & 0 deletions app/Community/Data/UserRecentPostsPagePropsData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace App\Community\Data;

use App\Data\PaginatedData;
use App\Data\UserData;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript('UserRecentPostsPageProps<TItems = App.Data.ForumTopic>')]
class UserRecentPostsPagePropsData extends Data
{
public function __construct(
public UserData $targetUser,
public PaginatedData $paginatedTopics,
) {
}
}
3 changes: 3 additions & 0 deletions app/Community/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Community\Controllers\MessageController;
use App\Community\Controllers\MessageThreadController;
use App\Community\Controllers\UserCommentController;
use App\Community\Controllers\UserForumTopicCommentController;
use App\Community\Controllers\UserSettingsController;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
Expand Down Expand Up @@ -41,6 +42,8 @@ protected function mapWebRoutes(): void
Route::middleware(['inertia'])->group(function () {
Route::get('forums/recent-posts', [ForumTopicController::class, 'recentPosts'])->name('forum.recent-posts');

Route::get('user/{user}/posts', [UserForumTopicCommentController::class, 'index'])->name('user.posts.index');

Route::get('settings', [UserSettingsController::class, 'show'])->name('settings.show');
});

Expand Down
99 changes: 0 additions & 99 deletions app/Community/Services/ForumRecentPostsPageService.php

This file was deleted.

2 changes: 1 addition & 1 deletion app/Data/ForumTopicCommentData.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function __construct(
public string $body,
public Carbon $createdAt,
public ?Carbon $updatedAt,
public UserData $user,
public ?UserData $user,
public bool $authorized, // TODO migrate to $authorizedAt
public ?int $forumTopicId = null,
) {
Expand Down
33 changes: 29 additions & 4 deletions app/Data/ForumTopicData.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public function __construct(
public string $title,
public Carbon $createdAt,
public Lazy|ForumTopicCommentData $latestComment,
public Lazy|int $commentCount24h,
public Lazy|int $oldestComment24hId,
public Lazy|int $commentCount7d,
public Lazy|int $oldestComment7dId,
public Lazy|int|null $commentCount24h,
public Lazy|int|null $oldestComment24hId,
public Lazy|int|null $commentCount7d,
public Lazy|int|null $oldestComment7dId,
public ?UserData $user = null,
) {
}
Expand Down Expand Up @@ -54,4 +54,29 @@ public static function fromRecentlyActiveTopic(array $topic): self

);
}

public static function fromUserPost(array $userPost): self
{
return new self(
id: $userPost['ForumTopicID'],
title: $userPost['ForumTopicTitle'],
createdAt: Carbon::parse($userPost['PostedAt']),

user: null,

commentCount24h: null,
oldestComment24hId: null,
commentCount7d: null,
oldestComment7dId: null,

latestComment: Lazy::create(fn () => new ForumTopicCommentData(
id: $userPost['CommentID'],
body: Shortcode::stripAndClamp($userPost['ShortMsg'], 200),
createdAt: Carbon::parse($userPost['PostedAt']),
updatedAt: null,
user: null,
authorized: true
)),
);
}
}
Loading

0 comments on commit c5a9891

Please sign in to comment.