-
Notifications
You must be signed in to change notification settings - Fork 11
refactor: extract keyboard navigation handlers into separate methods … #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| private function handleNavigateLeft(): void | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| $this->selectedIndex = min(-1, $this->selectedIndex + 1); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+103
to
+106
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| private function handleNavigateRight(): void | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| $this->selectedIndex = max(-3, $this->selectedIndex - 1); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+108
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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 |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 🧩 Analysis chainAdd PHPDoc and verify array access safety. Add PHPDoc per coding guidelines. Also verify that 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 🏁 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.phpLength 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 -20Length of output: 5553 Add PHPDoc to handleEnterKey and DRY duplicate toggle logic
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| private function handleQuit(): void | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| outro('See you later!'); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+158
to
+161
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| private function handleEditProfile(array $feeds): Collection | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| system('clear'); | ||||||||||||||||||||||||||||||||||||||||||
| $this->call(EditProfileCommand::class); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return $feeds[$this->activeFeed](); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+163
to
+169
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||
| * @param Collection<int, \App\Models\Post> $posts | ||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -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, | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
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.
📝 Committable suggestion
🤖 Prompt for AI Agents