Notifications & Messages Improvements โ
Overview โ
Updated the notification system and message handling in Lantern to be more elegant, persistent, and user-friendly.
Changes Implemented โ
1. Notification Persistence โ โ
Problem: Notifications disappeared when dismissed or the app reloaded, but would show again on next message.
Solution: Added localStorage-based persistence tracking
- File: src/screens/dashboard/Dashboard.jsx
- Implementation:
- Track dismissed notification IDs in
dismissedNotificationIdsstate (loaded from localStorage on mount) - When user dismisses a notification, save the ID to
localStorage.lantern_dismissed_notifications - Notifications that have been dismissed stay dismissed even after page reload
- Optional: Add expiration timer to auto-clear old dismissals after 24 hours (see Future Improvements)
- Track dismissed notification IDs in
const [dismissedNotificationIds, setDismissedNotificationIds] = useState(() => {
try {
const stored = localStorage.getItem('lantern_dismissed_notifications')
return new Set(stored ? JSON.parse(stored) : [])
} catch {
return new Set()
}
})
const dismissNotification = (id) => {
setNotifications(prev => prev.filter(n => n.id !== id))
setDismissedNotificationIds(prev => {
const updated = new Set(prev)
updated.add(id)
try {
localStorage.setItem('lantern_dismissed_notifications', JSON.stringify(Array.from(updated)))
} catch (e) {
console.warn('Failed to persist dismissed notifications:', e)
}
return updated
})
}2. Redesigned Notification UI โ โ
Problem: Notifications were small, indented boxes. They weren't visually prominent or easily scannable.
Solution: Full-width, top-anchored notifications with color coding by type
Changes:
Notifications now span the full viewport width with no side padding
Stack seamlessly at the top with no gaps between them (border-bottom only)
Color coded by type:
- Blue (
bg-blue-600/90) - New Messages - Amber (
bg-amber-600/90) - Wave Accepted - Red (
bg-red-600/90) - Errors (future use) - Green (
bg-green-600/90) - Success (future use) - White (
bg-white/80) - General messages
- Blue (
Each notification includes:
- Type-specific icon in a colored circle
- Message text
- Dismiss button (X) that persists dismissal to localStorage
- Hover effect with brightness increase for interactivity
File: src/screens/dashboard/Dashboard.jsx
{/* Full-width Notifications with type-based color coding */}
{notifications.length > 0 && (
<div className="fixed top-0 left-0 right-0 flex flex-col z-50 w-full">
{notifications.map(n => {
// Color scheme per notification type
const notificationStyles = {
message: { bg: 'bg-blue-600/90', ... },
accepted: { bg: 'bg-amber-600/90', ... },
error: { bg: 'bg-red-600/90', ... },
success: { bg: 'bg-green-600/90', ... },
default: { bg: 'bg-white/80', ... }
}
// ...render with full-width styling
})}
</div>
)}3. Message Deletion โ โ
Problem: Users couldn't delete messages they'd sent in error.
Solution: Added delete button to own messages with hover reveal
Changes:
Chat Component Updates โ
- File: src/components/Chat.jsx
- Added
Trash2icon import from lucide-react - Added
deletingMessageIdstate to track in-progress deletions - Delete button appears on hover (right side of message) for messages you sent ("You")
- Clicking delete prompts confirmation, then calls
deleteMessage()
{/* Delete button - only for own messages, appears on hover */}
{msg.senderName === 'You' && (
<button
onClick={() => handleDeleteMessage(msg.id)}
disabled={deletingMessageId === msg.id}
className="absolute -right-10 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-opacity p-1.5 text-zinc-400 hover:text-red-400 hover:bg-red-500/10 rounded-lg disabled:opacity-50"
title="Delete message"
>
<Trash2 size={16} />
</button>
)}Message Service Updates โ
- File: src/lib/messageService.js
- Added
deleteDocimport from firebase/firestore - New
deleteMessage()function:- Deletes message from
connections/{connectionId}/messages/{messageId} - Real-time listener automatically updates UI when deletion completes
- Error handling with user feedback
- Deletes message from
export async function deleteMessage(connectionId, messageId) {
try {
if (!connectionId || !messageId) {
throw new Error('Connection ID and Message ID required')
}
const messageRef = doc(db, CONNECTIONS_COLLECTION, connectionId, 'messages', messageId)
await deleteDoc(messageRef)
console.log(`๐๏ธ Message deleted from connection ${connectionId}`)
} catch (error) {
console.error('Error deleting message:', error)
throw error
}
}User Experience Flow โ
Notifications โ
- First time seeing notification: Appears at top in full-width color-coded format
- User dismisses (via X button):
- Removed from UI
- ID saved to localStorage
- Won't appear again (even if same message type received again)
- Page reload: Previously dismissed notifications don't reappear
Messages โ
- Hover over own message: Delete button appears on right side
- Click delete button: Confirmation dialog
- Confirm: Message deleted from Firestore
- Real-time sync: Chat updates automatically for both users
Firestore Rules โ
Message deletion respects existing Firestore security rules. Ensure your rules only allow users to delete their own messages:
allow delete: if request.auth.uid == resource.data.senderId;See firestore.rules for complete rules.
Files Changed โ
- src/screens/dashboard/Dashboard.jsx - Notification persistence & redesign
- src/components/Chat.jsx - Message deletion UI
- src/lib/messageService.js -
deleteMessage()function
Future Improvements โ
- Notification Expiration: Auto-clear dismissed notification IDs after 24 hours to prevent localStorage bloat
- Undo Deletion: Add temporary undo button after message deletion (e.g., 5-second window)
- Message Edit: Allow editing own messages (timestamp shows "edited")
- Notification Sound: Audio cue for message notifications (with mute toggle in settings)
- Read Receipts: Show when other user has read your message
- Typing Indicator: Show "Them is typing..." while other user composes
- Archive Chats: Archive old conversations instead of just closing
- Notification Filters: User control over which notification types to show
Testing โ
Notification Persistence โ
- [ ] Send notification โ dismiss โ reload page โ verify notification doesn't reappear
- [ ] Clear localStorage โ send same notification again โ should appear
- [ ] DevTools > Application > LocalStorage > check
lantern_dismissed_notificationsJSON
Notification UI โ
- [ ] Verify notifications span full width
- [ ] Test color coding: Blue (message), Amber (accepted wave), etc.
- [ ] Verify dismiss button works and persists dismissal
- [ ] Check responsive behavior on different viewport widths
Message Deletion โ
- [ ] Send message โ hover โ delete button appears
- [ ] Click delete โ confirmation dialog โ delete
- [ ] Verify message disappears for both users (real-time)
- [ ] Try to delete other user's message (should not show delete button)
- [ ] Check Firestore rules prevent cross-user deletion