-
Notifications
You must be signed in to change notification settings - Fork 520
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
#716 | [TASK]: Refactor Multiplayer & Typing Logic #721
Open
Ragudos
wants to merge
30
commits into
webdevcody:main
Choose a base branch
from
Ragudos:refactor-multiplayer
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…e-racer into refactor-multiplayer
Here it is. Take note that I've changed the logic from keydowns to onchange. If we'd like it to still be keydown, then it won't be a problem. |
So, I reran it again, and it still fails. I checked the following that failed, and they exist Namely: [data-cy='language-dropdown'] and [data-cy='search-language-input']: <Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
className={cn("justify-between w-full px-4 py-3", className)}
data-cy="language-dropdown"
>
{value
? snippetLanguages.find((language) => language.value === value)
?.label
: "Select language..."}
<ChevronsUpDown className="w-4 h-4 ml-2 opacity-50 shrink-0" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-full p-0 h-44">
<Command>
<CommandInput
placeholder="Search a Language..."
value={search}
onValueChange={setSearch}
data-cy="search-language-input"
/>
<CommandEmpty>No language found.</CommandEmpty>
<CommandGroup className="overflow-y-auto">
{snippetLanguages
.filter((language) =>
language.label.toLowerCase().includes(search.toLowerCase()),
)
.map((language) => (
<CommandItem
key={language.label}
value={language.value}
onSelect={(currentValue) => {
const parsedValue = languageTypes.parse(currentValue);
onChange(parsedValue);
window.localStorage.setItem(
"codeLanguage",
parsedValue,
);
setOpen(false);
}}
data-cy={`${language.value}-value`}
>
<Check
className={cn(
"mr-2 h-4 w-4",
value === language.value ? "opacity-100" : "opacity-0",
)}
/>
{language.label}
</CommandItem>
))}
</CommandGroup>
</Command>
</PopoverContent>
</Popover> Practice Race Card or [data cy='practice-card']: <Card
className="flex flex-col justify-between flex-1 border-2 border-warning"
data-cy="practice-card"
>
<CardHeader>
<div className="grid text-center place-content-center">
<Target className="justify-self-center" size={40} />
<h2
style={bruno_ace_sc.style}
className="text-3xl font-bold text-warning"
>
Practice
</h2>
<p className="font-light">
Practice typing with a random snippet from your snippets
</p>
</div>
</CardHeader>
<CardContent>
<form
onSubmit={handleSubmit}
className="grid items-start grid-cols-2 gap-2"
>
<div className="flex flex-col">
<LanguageDropDown
className={cn(
"w-full",
buttonVariants({ variant: "ghost" }),
error && "border-red-500",
)}
value={selectedPracticeLanguage}
onChange={handleSetCodeLanguage}
/>
<span className="text-red-500">{error}</span>
</div>
<Button
disabled={selectedPracticeLanguage === undefined}
variant="black"
className="relative justify-start border"
data-cy="practice-button"
>
Practice{" "}
<ArrowRight
size="20"
className="absolute -translate-y-1/2 right-4 top-1/2"
/>
</Button>
</form>
</CardContent>
</Card> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
title: #716 | [TASK]: Refactor Multiplayer & Typing Logic
Discord Username: @aaronragudos
What type of PR is this? (select all that apply)
Description
Large refactor of the race logic of the game. Namely:
First, I made the logic for typing, instead of handleKeyDowns, to listen to onChange. This is simpler, in my opinion, since we won't be doing slices, and such, as much as possible. Refactored the typing logic to be reusable as well using useReducer, and added some optimizations (useMemo, useCallback, and memo). Second, I added a button in practice to get a new snippet if a user wanted to.
Third, I finished the prototype for the room multiplayer functionality using the new typing logic. Lastly, I refactored the websocket server to separate the memory/state handling and the logic for the game (checking for status, etc.). I also made it clear about what a function does (well, not all of them, could do with more abstraction, but it's good for now).
Take note: The current rooms implementation does not do any call to the database except for when getting a snippet (getRandomSnippet).
The client will only connect to the socket if a user want to play multiplayer. I added autoConnect: false to the socket config.
Securities:
A user who's logged in cannot connect to the socket again. They must be disconnected.
The socket uses middleware to initialize a user (displayName, displayImage, userID).
If a user is not logged in, the provided socket.id is used instead.
If a room is not "waiting" and is either on "countdown", or "running" states and a user leaves, the server will check if there is one player remaining (for example, two users will play and one leaves). If there is only one player left, then the room will go back to "waiting" state no matter what.
If a room owner leaves the room, the next room owner will be the player that came after the room owner.
When a race is finished, a room owner can restart the game.
We can add displayNames when joining a room using searchqueries. If there is no displayName provided, we use either:
Possible features:
Related Tickets & Documents
QA Instructions, Screenshots, Recordings
TESTS TAKEN ON:
How can you test the changes?
For typing changes (on practice):
Go to Practice Race
Try to choose a language that does not exist in your local database. A message like "Uh oh", should show.
Now, try to choose a language that exists.
Click on the snippet, a focus indicator should then pop up (outline) on the black rectanlge.
The snippet should not overflow and should break into new lines.
As you type, the progress bar should track the changes and the row line tracker (the number on the side) should track the current line you are in. The row line tracker will based on whether you have typed a new Enter (⏎) character.
The timer should be running at this point.
Try clicking Reset.
This should reset your progress and time.
Now type something again and click Get New Snippet.
A loading indicator "Getting Snippets..." should replace the text on the button and the whole black rectangle should be disabled (buttons, textarea, etc.).
Try finishing a race.
The result page should:
a. use sessionStorage
b . Display the words you typed for each timestamp (for example, on the first timestamp, you would have "c", then on the next, it will be "co", and on another, "coo", etc.).
c. The graph should be displayed and on each hover of the timestamp, the snippet displayed below should follow (highlight) the latest character type.
d. Not have topten and history tabs
e. Should have a replay
f. Be able to play again with the snippet you used.
The replay should:
a. Play on pressing play button.
b. Stop when pressing pause
c. Restart and pause when pressing rotating arrow button
d. Stop playing and is paused when the replay finishes.
e. Play from the top upon playing the play button when the replay has finsihed.
f. Should follow how you typed everything on the snippet.
For multiplayer:
a. Room is being created
b. Room has been created, then the room should show up.
https://discord.com/channels/663478877355507769/1126627632461643797/1150827943749226647
NOTE:
This change needs more refactoring just to make things cleaner and add the integration of the database.
UI accessibility concerns?
Added/updated tests?
E2E tests still aren't updated, so I'm not sure how it will affect stuff. Don't worry, I believe the multiplayer mode will only show up on development for this version.
[optional] Are there any post deployment tasks we need to perform?
[optional] What gif best describes this PR or how it makes you feel?
Very fine. I've enjoyed tinkering around with the codebase