Skip to content

feat: add typing indicator for better UI experience issue #8#39

Open
Shreenath-14 wants to merge 7 commits intoZenYukti:mainfrom
Shreenath-14:feat-typing-indicator
Open

feat: add typing indicator for better UI experience issue #8#39
Shreenath-14 wants to merge 7 commits intoZenYukti:mainfrom
Shreenath-14:feat-typing-indicator

Conversation

@Shreenath-14
Copy link
Contributor

Description

Implemented a real-time typing indicator for the chat interface. This provides visual feedback when another user is typing, improving the overall user experience and communication flow within rooms. Closes #8.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🧹 Code refactoring (no functional changes)
  • ⚡ Performance improvement
  • ✅ Test improvement
  • 🔧 Build or CI/CD configuration changes

How Has This Been Tested?

  • Real-time Verification: Tested using two separate browser windows (one in Incognito mode) to ensure the "God is typing..." indicator appears correctly when the other user enters text.
  • WebSocket Stability: Verified that the typing event is correctly handled by the backend and broadcasted to other participants without lag.

Screenshots

image

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Additional Information

Learning Outcomes

I learned how to handle real-time event broadcasting using WebSockets to synchronize UI states across multiple clients.

@Shreenath-14
Copy link
Contributor Author

Hi Team! This is the separated PR for the typing indicator (Issue #8). It includes the WebSocket logic and UI updates. I've verified it works locally with multiple users.

@ayushHardeniya ayushHardeniya added apertre3.0 Apertre 3.0 open source program easy simple fixes requiring minimal project knowledge. frontend Client-side features and views ui/ux labels Feb 13, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Shreenath-14
Copy link
Contributor Author

Hey @ayushHardeniya , @Blazzzeee
Its been week on creating this pr and I think you have to declare the result and close the issue no #8

@Blazzzeee
Copy link
Collaborator

yeah ill review it today night , sorry for being late

@Shreenath-14
Copy link
Contributor Author

Hey @Blazzzeee
Its been week on creating this pr and I think you have to declare the result and close the issue no #8/
Last time you said I'll review by today but after that you havn't replied bro

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a real-time “user is typing…” indicator to the room chat experience by introducing a new typing WebSocket message and UI rendering in the chat room.

Changes:

  • Add a typing WebSocket message type on both frontend and backend, including a sendTyping helper in the client hook.
  • Track and render currently-typing users in ChatRoom.
  • Adjust API request header typing/merging logic in apiFetch.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
frontend/src/lib/api.ts Changes header typing/merge approach for authenticated API calls.
frontend/src/hooks/useWebSocket.ts Adds typing to message types and exposes sendTyping.
frontend/src/components/ChatRoom.tsx Adds typing-users state, debounced typing emission, and typing indicator UI.
backend/src/services/chatServer.ts Handles incoming typing messages and broadcasts typing state to other room members.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Blazzzeee
Copy link
Collaborator

@Shreenath-14 bhot sari chizo ka type any hai , there have been no commits to fix that,

@Blazzzeee
Copy link
Collaborator

@Shreenath-14 also websocket me resource leak hai useWebSocket me page change hone pe sb connectiobn purge krne hoge

@Blazzzeee
Copy link
Collaborator

@Shreenath-14 fix alll these issues pls

@Shreenath-14
Copy link
Contributor Author

I'll fix all by tomorrow

@Shreenath-14
Copy link
Contributor Author

I have completed a full refactor to address all the issues raised during review. The codebase is now fully type-safe, and both frontend and backend builds are passing perfectly.

Summary of Key Fixes:

  • Type Safety: Removed all as any casts in chatServer.ts and introduced a properly typed AuthenticatedWebSocket interface.
  • Resource Leak: Fixed the WebSocket resource leak by stripping onclose handlers during manual disconnects.
  • Performance: Optimized the debounce logic to 1000ms for a smoother UI without server strain.
  • State Management: Added useEffect cleanup in ChatRoom.tsx to clear timeouts and reset typing state on unmount.
  • Logic Cleanup: Removed leftover crisis_alert remnants and resolved TypeScript narrowing issues in crisisDetection.ts.

Branch has been synced with main. Ready for final review! cc @Blazzzeee

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • backend/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Blazzzeee
Copy link
Collaborator

@Shreenath-14 please review the code before submitting ai generated code , be mindfull i have to manually review a lot of slop code , the goal isnt getting a issue closed .......

@Shreenath-14
Copy link
Contributor Author

Shreenath-14 commented Mar 3, 2026

I apologies for the previous overhead. I went back through and refactored the logic manually to keep it minimal and efficient.

@Shreenath-14
Copy link
Contributor Author

@Blazzzeee Bro please pay attention on this

@Blazzzeee
Copy link
Collaborator

yeah i have work to do too , please mind a buffer of 3-4 days atleast to reviewers

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • backend/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)

frontend/src/components/ChatRoom.tsx:154

  • handleSendMessage doesn’t clear the typing indicator. If the user submits right after typing, other clients may continue seeing “typing…” until the 2s debounce fires. Clear any pending timeout and send sendTyping(false) as part of the submit path (and consider doing the same on input blur) so the indicator clears immediately on send.
  const handleSendMessage = (e: React.FormEvent) => {
    e.preventDefault();

    if (!inputValue.trim() || !isConnected) {
      return;
    }

    const success = sendMessage(inputValue.trim());
    if (success) {
      setInputValue('');
    }
  };

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +134 to +139
// Clear typing timeout and reset typing users on unmount
return () => {
if (typingTimeoutRef.current) {
clearTimeout(typingTimeoutRef.current);
}
setTypingUsers(prev => prev.size > 0 ? EMPTY_SET : prev);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The unmount cleanup calls setTypingUsers(...). Setting state during unmount is unnecessary (the component is being removed) and can lead to noisy warnings in some React setups. Consider removing the state update here; clearing the timeout is sufficient.

Suggested change
// Clear typing timeout and reset typing users on unmount
return () => {
if (typingTimeoutRef.current) {
clearTimeout(typingTimeoutRef.current);
}
setTypingUsers(prev => prev.size > 0 ? EMPTY_SET : prev);
// Clear typing timeout on unmount
return () => {
if (typingTimeoutRef.current) {
clearTimeout(typingTimeoutRef.current);
}

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

ignore

Comment on lines 78 to 92
type: 'system',
},
]);
} else if (message.type === 'crisis_alert') {
setShowCrisisAlert(true);
setTimeout(() => setShowCrisisAlert(false), 10000);
} else if (message.type === 'typing') {
const { nickname, isTyping } = message;
setTypingUsers((prev) => {
const newSet = new Set(prev);
if (isTyping) {
newSet.add(nickname);
} else {
newSet.delete(nickname);
}
return newSet;
});
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

useWebSocket / backend can send a crisis_alert message (with a message field for resources), but this handler doesn’t currently handle message.type === 'crisis_alert'. That means the sender won’t see the crisis resources payload. Add a crisis_alert branch (or remove/replace the backend event) so the message type is either rendered or explicitly ignored with a clear UX decision.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

ignore for now

Comment on lines +103 to +112
if (roomId && userId) {
const isTyping = typeof message.isTyping === 'boolean' ? message.isTyping : false;
// Broadcast to other users in the room
this.broadcastToRoom(roomId, {
type: 'typing',
userId,
nickname,
isTyping,
}, userId); // Exclude sender
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

handleTyping trusts ws.roomId/userId metadata without verifying the socket is still a member of that room. Because handleLeave removes the member from the room set but doesn’t clear ws.roomId/userId, a client that sends leave (but keeps the connection open) can still broadcast typing events to the room. Consider either clearing ws.roomId/ws.userId/ws.nickname on leave, and/or checking membership in this.rooms.get(roomId) before broadcasting.

Suggested change
if (roomId && userId) {
const isTyping = typeof message.isTyping === 'boolean' ? message.isTyping : false;
// Broadcast to other users in the room
this.broadcastToRoom(roomId, {
type: 'typing',
userId,
nickname,
isTyping,
}, userId); // Exclude sender
}
// Ensure the socket is still a member of the room before broadcasting
if (!roomId || !userId) {
return;
}
const roomMembers = this.rooms.get(roomId);
if (!roomMembers) {
return;
}
const isMember = Array.from(roomMembers).some((member) => member.ws === ws);
if (!isMember) {
return;
}
const isTyping = typeof message.isTyping === 'boolean' ? message.isTyping : false;
// Broadcast to other users in the room
this.broadcastToRoom(
roomId,
{
type: 'typing',
userId,
nickname,
isTyping,
},
userId, // Exclude sender
);

Copilot uses AI. Check for mistakes.
@Shreenath-14
Copy link
Contributor Author

Shreenath-14 commented Mar 6, 2026

@Blazzzeee Bro that's enough I know you have some other work too but it was my first issue which I got at the starting and its the last moment where the program got end in next day still you are saying make those changes if you see this is the easy task where I just have to implement indicator and I did it well and if you see the current state of project then there is already the indicator is working because as a beginner I don't know "How those things work" but then I get cleared how to work on a open source project issue. And now at this point I'm also frustrated because when I raised the PR all things are good and sorry if I disappointed you but understand this feature is implemented on consideration of easy task. If needed further enhancement then I think you have to raise new issue on enhancement in typing indicator.

And one last the previous PR which add this in feature is also created by me. so think and respond please as quick as possible and as an ai tester it suggest everytime you ask.

@Blazzzeee
Copy link
Collaborator

@Shreenath-14 the reason i have to merge code is to maintain code quality , your code produces what the issue needs , however it doesnt mean code quality can be neglected , besides alot of these issues are legit problems in your code . If you think if the thing working for a specific local use case means it should be merged , you are very wrong by that ....

minor: change setkey to userid from nickname (duplication fix)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Comment on lines +134 to +139
// Clear typing timeout and reset typing users on unmount
return () => {
if (typingTimeoutRef.current) {
clearTimeout(typingTimeoutRef.current);
}
setTypingUsers(prev => prev.size > 0 ? EMPTY_SET : prev);
Copy link
Collaborator

Choose a reason for hiding this comment

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

ignore

Comment on lines 78 to 92
type: 'system',
},
]);
} else if (message.type === 'crisis_alert') {
setShowCrisisAlert(true);
setTimeout(() => setShowCrisisAlert(false), 10000);
} else if (message.type === 'typing') {
const { nickname, isTyping } = message;
setTypingUsers((prev) => {
const newSet = new Set(prev);
if (isTyping) {
newSet.add(nickname);
} else {
newSet.delete(nickname);
}
return newSet;
});
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

ignore for now

@Blazzzeee
Copy link
Collaborator

@ayushHardeniya take the pull

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apertre3.0 Apertre 3.0 open source program easy simple fixes requiring minimal project knowledge. frontend Client-side features and views triage-needed ui/ux

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No way to tell if someone's typing

4 participants