-
Notifications
You must be signed in to change notification settings - Fork 3
Fixed Long para typing issue #3 #3
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?
Conversation
|
@its-nihit-0407 is attempting to deploy a commit to the deepak's projects Team on Vercel. A member of the Team first needs to authorize it. |
Reviewer's GuideThis PR fixes the long-paragraph typing issue by improving state management and input handling in TypingBoard, adding a restart button with reload fallback in the completion screen, and ensuring navigation links force full page reloads. Sequence Diagram: Game Restart Process from TypingCompleteScreensequenceDiagram
actor User
participant TCS as TypingCompleteScreen
participant ParentComponent as Parent Component (Handles Restart)
participant Window as Browser Window
User->>TCS: Clicks Restart Button
activate TCS
TCS->>TCS: Calls handleGameRestart()
alt onRestart prop is available (function)
TCS->>ParentComponent: Calls onRestart()
activate ParentComponent
ParentComponent->>ParentComponent: Resets game state / reloads data
deactivate ParentComponent
else onRestart prop is not available
TCS->>Window: Calls window.location.reload()
end
deactivate TCS
Sequence Diagram: Navigation with Full Page Reload via reloadDocumentsequenceDiagram
actor User
participant SB as SideBar
participant NL as NavLink / ParaLink
participant Browser
User->>SB: Clicks a navigation link (e.g., "infinite mode")
SB->>NL: Renders with reloadDocument prop set to true
NL->>Browser: Navigates to link's target route
Browser->>Browser: Performs a full page reload and fetches new page
activate Browser
deactivate Browser
Class Diagram: Updated TypingBoard ComponentclassDiagram
class TypingBoard {
+State:
-quote: string
-currentIdx: number
-typedChars: string
-wordsPressed: number
-rightWords: number
-warning: boolean
-typos: number
-isCompeleted: boolean
-finalTime: number
-WPM: number
-accuracy: number
+Props:
-quotes: string
+Key Logic:
#useEffect_onQuotesChange() : void (New: Cleans quote, resets all game-related states when props.quotes changes)
#handleKeyDown(event) : void (Modified: Ignores input if completed, allows wider range of chars e.g. punctuation, fixed warning state update)
}
Class Diagram: Updated TypingCompleteScreen ComponentclassDiagram
class TypingCompleteScreen {
+Props:
-finalTime: number
-WPM: number
-accuracy: number
-onRestart: function (New)
+Key Logic:
#handleGameRestart() : void (New: Calls onRestart prop if it's a function, otherwise reloads the page)
}
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
Hey @its-nihit-0407 - I've reviewed your changes - here's some feedback:
- Your useEffect for keydown events doesn’t remove the listener on unmount or declare proper dependencies—add a cleanup return and dependency array to avoid stale closures and memory leaks.
- There are leftover commented console.logs and unused imports (useLocation/useNavigate) in TypingCompleteScreen—remove them for cleaner code.
- The reset logic inside the props.quotes useEffect is quite verbose; consider extracting it into a standalone reset function or custom hook to improve readability and maintainability.
Here's what I looked at during the review
- 🟡 General issues: 1 issue found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟡 Complexity: 1 issue found
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| const pressedKey = e.key; | ||
|
|
||
| // Don't process if typing is completed | ||
| if (isCompeleted) return; |
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.
issue (typo): Correct spelling of isCompeleted
Use the correct spelling (isCompleted) for clarity and consistency.
Suggested implementation:
// Don't process if typing is completed
if (isCompleted) return;You will also need to rename all other occurrences of isCompeleted to isCompleted in this file (and possibly elsewhere in your codebase) to maintain consistency and avoid reference errors.
|
|
||
| const TypingBoard = (props) => { | ||
| // console.log(props.quotes) | ||
| const [words, setWords] = useState([]) |
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.
issue (complexity): Consider refactoring multiple related useState hooks into a single useReducer with a RESET action to centralize and simplify state management.
Here’s one way to collapse all of those individual setters into a single reducer with a RESET action. You’ll end up with one state object and one place that describes how it changes:
// 1) Move your “shape” into a single object
const makeInitialState = (rawQuote) => {
const cleaned = rawQuote.trim().replace(/\s+/g, ' ')
return {
quote: cleaned,
currentIdx: 0,
typedChars: '',
wordsPressed: 0,
rightWords: 0,
warning: true,
typos: 0,
isCompleted: false,
finalTime: 0,
WPM: 0,
accuracy: 0,
}
}
// 2) A reducer that handles RESET (and later could handle KEY_PRESS, etc)
function sessionReducer(state, action) {
switch (action.type) {
case 'RESET':
return makeInitialState(action.quote)
// you can add more actions here, e.g. KEY_PRESS
default:
return state
}
}
const TypingBoard = ({ quotes }) => {
// 3) swap all your useStates for one useReducer
const [session, dispatch] = useReducer(
sessionReducer,
makeInitialState(quotes)
)
// 4) on props.quotes change just RESET in one line
useEffect(() => {
dispatch({ type: 'RESET', quote: quotes })
}, [quotes])
// 5) in your key handler you can dispatch KEY_PRESS instead of 10 setters
useEffect(() => {
const handleKeyDown = e => {
if (session.isCompleted) return
// …
// dispatch({ type: 'KEY_PRESS', key: e.key })
}
document.addEventListener('keydown', handleKeyDown)
return () => document.removeEventListener('keydown', handleKeyDown)
}, [session, dispatch])
// …render using session.currentIdx, session.typedChars, etc.
}Benefits:
- All reset logic lives in one place
- No more “setX” duplication
- Easier to add new actions (typo counting, completion, etc.) without scattering setters.
| const pressedKey = e.key; | ||
|
|
||
| // Don't process if typing is completed | ||
| if (isCompeleted) return; |
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.
suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces)
| if (isCompeleted) return; | |
| if (isCompeleted) { |
Explanation
It is recommended to always use braces and create explicit statement blocks.Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).
After Changes
solved.mp4
Before Changes
not.mp4
Summary by Sourcery
Improve typing board state management and input validation to support long paragraphs, add restart functionality on completion, and ensure proper page reloads on navigation
New Features:
Bug Fixes:
Enhancements:
Chores: