Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 89 additions & 40 deletions app/Console/Commands/FeedCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,57 +68,106 @@ public function handle(
$key = $this->captureKeyPress();

if ($key === Key::UP || $key === 'k') {
if ($this->selectedIndex >= 0) {
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
}
$this->handleNavigateUp();
} elseif ($key === Key::DOWN || $key === 'j') {
$this->selectedIndex = $this->selectedIndex < 0 ? 0 : min($posts->count() - 1, $this->selectedIndex + 1);
$this->handleNavigateDown($posts);
} elseif (($key === Key::LEFT || $key === 'h') && $this->selectedIndex < 0) {
$this->selectedIndex = min(-1, $this->selectedIndex + 1);
$this->handleNavigateLeft();
} elseif ($key === Key::RIGHT && $this->selectedIndex < 0) {
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
$this->handleNavigateRight();
} elseif ($key === 'l' && $this->selectedIndex >= 0) {
$post = $posts->all()[$this->selectedIndex];
$likedByCurrentUser = $post->likes->contains('user_id', $user->id);

if ($likedByCurrentUser) {
$unlikeAction->handle($post, $user);
} else {
$likeAction->handle($post, $user);
}

$posts = $feeds[$this->activeFeed]();
$posts = $this->handleToggleLike($posts, $user, $likeAction, $unlikeAction, $feeds);
} elseif ($key === Key::ENTER || $key === "\r") {
if ($this->selectedIndex < 0) {
$headerIndex = abs($this->selectedIndex) - 1;
$feedKeys = ['following', 'trending', 'profile'];
$this->activeFeed = $feedKeys[$headerIndex];
$posts = $feeds[$this->activeFeed]();
$this->scrollOffset = 0;
} else {
$post = $posts->all()[$this->selectedIndex];
$likedByCurrentUser = $post->likes->contains('user_id', $user->id);

if ($likedByCurrentUser) {
$unlikeAction->handle($post, $user);
} else {
$likeAction->handle($post, $user);
}

$posts = $feeds[$this->activeFeed]();
}
$posts = $this->handleEnterKey($posts, $user, $likeAction, $unlikeAction, $feeds);
} elseif ($key === 'q') {
outro('See you later!');

$this->handleQuit();
return;
} elseif ($key === 'e' && $this->activeFeed === 'profile') {
system('clear');
$this->call(EditProfileCommand::class);
$posts = $feeds[$this->activeFeed]();
$posts = $this->handleEditProfile($feeds);
}
}
}

private function handleNavigateUp(): void
{
if ($this->selectedIndex >= 0) {
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
}
}
Comment on lines +91 to +96
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add PHPDoc block.

Per coding guidelines, prefer PHPDoc blocks for methods. Add documentation explaining the navigation behavior.

As per coding guidelines.

+/**
+ * Navigate up from a post to the header.
+ * Decrements selection index with a lower bound of -3.
+ */
 private function handleNavigateUp(): void
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private function handleNavigateUp(): void
{
if ($this->selectedIndex >= 0) {
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
}
}
/**
* Navigate up from a post to the header.
* Decrements the selection index with a lower bound of -3.
*/
private function handleNavigateUp(): void
{
if ($this->selectedIndex >= 0) {
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
}
}
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 91 to 96, add a PHPDoc
block for the private method handleNavigateUp() describing its purpose and
behavior: state that it moves the selection up by decrementing
$this->selectedIndex by 1 when the current index is >= 0, with a lower bound of
-3, and include the @return void annotation; keep the doc concise and follow
project PHPDoc style.


private function handleNavigateDown(Collection $posts): void
{
$this->selectedIndex = $this->selectedIndex < 0 ? 0 : min($posts->count() - 1, $this->selectedIndex + 1);
}
Comment on lines +98 to +101
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add PHPDoc block with parameter documentation.

Per coding guidelines, add PHPDoc describing the method and parameter type.

As per coding guidelines.

+/**
+ * Navigate down to the next post or jump from header to first post.
+ *
+ * @param Collection<int, \App\Models\Post> $posts
+ */
 private function handleNavigateDown(Collection $posts): void
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private function handleNavigateDown(Collection $posts): void
{
$this->selectedIndex = $this->selectedIndex < 0 ? 0 : min($posts->count() - 1, $this->selectedIndex + 1);
}
/**
* Navigate down to the next post or jump from header to first post.
*
* @param Collection<int, \App\Models\Post> $posts
*/
private function handleNavigateDown(Collection $posts): void
{
$this->selectedIndex = $this->selectedIndex < 0 ? 0 : min($posts->count() - 1, $this->selectedIndex + 1);
}
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 98 to 101, the private
method handleNavigateDown lacks a PHPDoc block; add a short PHPDoc comment
immediately above the method with a one-line description of what the method does
and an @param tag documenting the type (\Illuminate\Support\Collection) and
purpose of $posts and an @return void tag to satisfy the coding guidelines.


private function handleNavigateLeft(): void
{
$this->selectedIndex = min(-1, $this->selectedIndex + 1);
}
Comment on lines +103 to +106
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add PHPDoc block.

As per coding guidelines.

+/**
+ * Navigate left in the header (increment negative index).
+ */
 private function handleNavigateLeft(): void
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private function handleNavigateLeft(): void
{
$this->selectedIndex = min(-1, $this->selectedIndex + 1);
}
/**
* Navigate left in the header (increment negative index).
*/
private function handleNavigateLeft(): void
{
$this->selectedIndex = min(-1, $this->selectedIndex + 1);
}
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 103 to 106, the private
method handleNavigateLeft lacks a PHPDoc block; add a short PHPDoc immediately
above the method with a one-line description (e.g., "Handle navigation to the
left in the feed selection"), include the @return void tag and any relevant tags
(e.g., @access private if you follow that convention), and ensure the doc block
formatting follows project coding guidelines.


private function handleNavigateRight(): void
{
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
}
Comment on lines +108 to +111
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add PHPDoc block.

As per coding guidelines.

+/**
+ * Navigate right in the header (decrement negative index).
+ */
 private function handleNavigateRight(): void
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private function handleNavigateRight(): void
{
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
}
/**
* Navigate right in the header (decrement negative index).
*/
private function handleNavigateRight(): void
{
$this->selectedIndex = max(-3, $this->selectedIndex - 1);
}
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 108 to 111, the private
method handleNavigateRight is missing a PHPDoc block; add a PHPDoc comment
immediately above the method describing its purpose (e.g., "Move selection to
the right/clamp to minimum index"), include the @return void tag and any
relevant param/behavior notes, and keep it aligned with project docblock style
conventions.


private function handleToggleLike(
Collection $posts,
User $user,
LikeAction $likeAction,
UnlikeAction $unlikeAction,
array $feeds
): Collection {
$post = $posts->all()[$this->selectedIndex];
$likedByCurrentUser = $post->likes->contains('user_id', $user->id);

if ($likedByCurrentUser) {
$unlikeAction->handle($post, $user);
} else {
$likeAction->handle($post, $user);
}

return $feeds[$this->activeFeed]();
}
Comment on lines +113 to +130
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Extract duplicate like/unlike logic and add PHPDoc.

The like/unlike logic in this method duplicates code in handleEnterKey (lines 145-152). Extract to a shared private method to comply with DRY principles. Also add PHPDoc per coding guidelines.

As per coding guidelines.

Extract the logic:

/**
 * Toggle like status for the given post.
 */
private function togglePostLike(Post $post, User $user, LikeAction $likeAction, UnlikeAction $unlikeAction): void
{
    $likedByCurrentUser = $post->likes->contains('user_id', $user->id);

    if ($likedByCurrentUser) {
        $unlikeAction->handle($post, $user);
    } else {
        $likeAction->handle($post, $user);
    }
}

Then update both methods:

+/**
+ * Toggle like/unlike for the currently selected post.
+ *
+ * @param Collection<int, \App\Models\Post> $posts
+ * @param array<string, callable(): Collection<int, \App\Models\Post>> $feeds
+ * @return Collection<int, \App\Models\Post>
+ */
 private function handleToggleLike(
     Collection $posts,
     User $user,
     LikeAction $likeAction,
     UnlikeAction $unlikeAction,
     array $feeds
 ): Collection {
     $post = $posts->all()[$this->selectedIndex];
-    $likedByCurrentUser = $post->likes->contains('user_id', $user->id);
-
-    if ($likedByCurrentUser) {
-        $unlikeAction->handle($post, $user);
-    } else {
-        $likeAction->handle($post, $user);
-    }
+    $this->togglePostLike($post, $user, $likeAction, $unlikeAction);

     return $feeds[$this->activeFeed]();
 }
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 113 to 130, the like/unlike
toggle logic duplicates code also present in handleEnterKey; extract that logic
to a new private method with PHPDoc (e.g., togglePostLike(Post $post, User
$user, LikeAction $likeAction, UnlikeAction $unlikeAction): void) that checks if
$post->likes contains the current user and calls unlikeAction->handle or
likeAction->handle accordingly, then replace the duplicated blocks in both
handleToggleLike and handleEnterKey to call this new private method; ensure the
new method has a one-line PHPDoc summary per coding guidelines and update
affected calls to pass the Post and User and the two action instances.


private function handleEnterKey(
Collection $posts,
User $user,
LikeAction $likeAction,
UnlikeAction $unlikeAction,
array $feeds
): Collection {
if ($this->selectedIndex < 0) {
$headerIndex = abs($this->selectedIndex) - 1;
$feedKeys = ['following', 'trending', 'profile'];
$this->activeFeed = $feedKeys[$headerIndex];
$this->scrollOffset = 0;
} else {
$post = $posts->all()[$this->selectedIndex];
$likedByCurrentUser = $post->likes->contains('user_id', $user->id);

if ($likedByCurrentUser) {
$unlikeAction->handle($post, $user);
} else {
$likeAction->handle($post, $user);
}
}

return $feeds[$this->activeFeed]();
}
Comment on lines +132 to +156
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Add PHPDoc and verify array access safety.

Add PHPDoc per coding guidelines. Also verify that $headerIndex will always be valid (0, 1, or 2) for the $feedKeys array access on line 142.

As per coding guidelines.

+/**
+ * Handle ENTER key: switch feeds in header mode or toggle like on selected post.
+ *
+ * @param Collection<int, \App\Models\Post> $posts
+ * @param array<string, callable(): Collection<int, \App\Models\Post>> $feeds
+ * @return Collection<int, \App\Models\Post>
+ */
 private function handleEnterKey(

Run the following script to verify that selectedIndex values are always constrained to -3, -2, -1 when in header mode:


🏁 Script executed:

#!/bin/bash
# Verify that header navigation methods constrain selectedIndex to -3, -2, -1

echo "Checking handleNavigateLeft constrains to min -1:"
rg -nP 'handleNavigateLeft.*\{[\s\S]*?selectedIndex.*min\(-1' app/Console/Commands/FeedCommand.php

echo -e "\nChecking handleNavigateRight constrains to max -3:"
rg -nP 'handleNavigateRight.*\{[\s\S]*?selectedIndex.*max\(-3' app/Console/Commands/FeedCommand.php

echo -e "\nChecking handleNavigateUp prevents navigation when in header:"
rg -nP 'handleNavigateUp.*\{[\s\S]*?if.*selectedIndex >= 0' app/Console/Commands/FeedCommand.php

Length of output: 164


I need to examine the navigation methods more carefully to verify the constraints. Let me search for these methods directly.

</script>

🏁 Script executed:

#!/bin/bash
# Find and display the navigation methods to verify selectedIndex constraints

echo "=== handleNavigateLeft method ==="
rg -n 'handleNavigateLeft' app/Console/Commands/FeedCommand.php -A 20

echo -e "\n=== handleNavigateRight method ==="
rg -n 'handleNavigateRight' app/Console/Commands/FeedCommand.php -A 20

echo -e "\n=== handleNavigateUp method ==="
rg -n 'handleNavigateUp' app/Console/Commands/FeedCommand.php -A 20

echo -e "\n=== Check for selectedIndex initialization ==="
rg -n 'selectedIndex\s*=' app/Console/Commands/FeedCommand.php | head -20

Length of output: 5553


Add PHPDoc to handleEnterKey and DRY duplicate toggle logic

  • Add a PHPDoc block on handleEnterKey annotating Collection<int, App\Models\Post> $posts, User $user, LikeAction, UnlikeAction, array<string, callable():Collection<int, App\Models\Post>> $feeds, and its Collection<int, App\Models\Post> return.
  • Extract the duplicated like/unlike handling into a shared method (or call handleToggleLike) to avoid repeating the toggle logic.
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 132 to 156, add a PHPDoc
block for handleEnterKey annotating Collection<int, App\Models\Post> $posts,
User $user, LikeAction $likeAction, UnlikeAction $unlikeAction, array<string,
callable(): Collection<int, App\Models\Post>> $feeds and a return type of
Collection<int, App\Models\Post>, and refactor the duplicated like/unlike toggle
logic into a single method (e.g. handleToggleLike(User $user, Post $post,
LikeAction $likeAction, UnlikeAction $unlikeAction): void) or call the existing
handleToggleLike so the if/else that checks $post->likes->contains('user_id',
$user->id) is removed from handleEnterKey and replaced by a single call to that
helper.


private function handleQuit(): void
{
outro('See you later!');
}
Comment on lines +158 to +161
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add PHPDoc block.

As per coding guidelines.

+/**
+ * Exit the application with a farewell message.
+ */
 private function handleQuit(): void
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private function handleQuit(): void
{
outro('See you later!');
}
/**
* Exit the application with a farewell message.
*/
private function handleQuit(): void
{
outro('See you later!');
}
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 158 to 161, the private
method handleQuit() lacks a PHPDoc block; add a short PHPDoc above the method
describing its purpose (e.g., "Display exit message"), include the @return void
tag and note there are no parameters, and keep visibility and signature
unchanged (private function handleQuit(): void). Ensure the PHPDoc follows
project style (/** ... */) and is placed immediately above the method
declaration.


private function handleEditProfile(array $feeds): Collection
{
system('clear');
$this->call(EditProfileCommand::class);

return $feeds[$this->activeFeed]();
}
Comment on lines +163 to +169
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add PHPDoc block.

As per coding guidelines.

+/**
+ * Open the profile editor and refresh the feed afterward.
+ *
+ * @param array<string, callable(): Collection<int, \App\Models\Post>> $feeds
+ * @return Collection<int, \App\Models\Post>
+ */
 private function handleEditProfile(array $feeds): Collection
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private function handleEditProfile(array $feeds): Collection
{
system('clear');
$this->call(EditProfileCommand::class);
return $feeds[$this->activeFeed]();
}
/**
* Open the profile editor and refresh the feed afterward.
*
* @param array<string, callable(): Collection<int, \App\Models\Post>> $feeds
* @return Collection<int, \App\Models\Post>
*/
private function handleEditProfile(array $feeds): Collection
{
system('clear');
$this->call(EditProfileCommand::class);
return $feeds[$this->activeFeed]();
}
🤖 Prompt for AI Agents
In app/Console/Commands/FeedCommand.php around lines 163 to 169, the private
method handleEditProfile lacks a PHPDoc block; add a concise PHPDoc above the
method describing its purpose, include @param array $feeds and @return
\Illuminate\Support\Collection (or Collection fully-qualified), and any relevant
@throws if applicable, ensuring the doc follows project coding guidelines and
matches the method signature.


/**
* @param Collection<int, \App\Models\Post> $posts
*/
Expand All @@ -141,7 +190,7 @@ private function renderFeed(User $user, Collection $posts, int $postsPerPage): v

$feedKeys = ['following', 'trending', 'profile'];
$activeFeedIndex = array_search($this->activeFeed, $feedKeys);

render(view($viewName, [
'user' => $user,
'posts' => $visiblePosts,
Expand Down