Skip to content

feat: add toast notification system #68

@nullcoder

Description

@nullcoder

Description

Implement a toast notification system for user feedback, with specific messages for GhostPaste operations.

Security Requirements

  • NEVER include sensitive data in toast messages (no keys, PINs, or decrypted content)
  • Error messages must be generic enough to not reveal system internals
  • Success messages should confirm action without exposing data

Toast Types & Messages

Success Messages

// Gist operations
"Gist created successfully"
"Share link copied to clipboard"
"Gist updated successfully"
"File copied to clipboard"

// Encryption operations (generic, no details)
"Content encrypted successfully"
"Content decrypted successfully"

Error Messages

// Generic errors that don't reveal sensitive info
"Failed to create gist. Please try again."
"Failed to decrypt content. Invalid or corrupted data."
"Network error. Please check your connection."
"Invalid PIN. Please try again."
"File size limit exceeded (max 500KB per file)"
"Total size limit exceeded (max 5MB per gist)"

Warning Messages

"This gist will expire in 1 hour"
"This is a one-time view gist"
"Maximum number of files reached (20)"

Info Messages

"Loading gist..."
"Generating encryption key..."
"Saving changes..."

Visual Design

Toast Variants

type ToastVariant = "success" | "error" | "warning" | "info" | "loading";

// Variant styles
const variantStyles = {
  success: "bg-green-50 text-green-900 dark:bg-green-900 dark:text-green-50",
  error: "bg-red-50 text-red-900 dark:bg-red-900 dark:text-red-50",
  warning: "bg-amber-50 text-amber-900 dark:bg-amber-900 dark:text-amber-50",
  info: "bg-blue-50 text-blue-900 dark:bg-blue-900 dark:text-blue-50",
  loading: "bg-gray-50 text-gray-900 dark:bg-gray-900 dark:text-gray-50"
};

Auto-dismiss Timers

  • Success: 3 seconds
  • Error: 5 seconds (user needs time to read)
  • Warning: 4 seconds
  • Info: 3 seconds
  • Loading: No auto-dismiss (dismiss when action completes)

Features

Toast Queue System

  • Maximum 3 toasts visible at once
  • New toasts push older ones up
  • Smooth enter/exit animations
  • Stacking with proper spacing

Positioning

  • Default: Bottom right corner
  • Mobile: Bottom center with full width
  • Offset from viewport edges: 16px
  • Stack spacing: 8px between toasts

Interactions

  • Manual dismiss with × button
  • Click to dismiss (optional)
  • Pause auto-dismiss on hover
  • Swipe to dismiss on mobile

Implementation with shadcn/ui

// Use shadcn/ui toast
import { useToast } from "@/components/ui/use-toast"
import { Toaster } from "@/components/ui/toaster"

// Custom hook for GhostPaste toasts
export function useGhostToast() {
  const { toast } = useToast();
  
  return {
    success: (message: string) => toast({
      title: message,
      variant: "success",
      duration: 3000,
    }),
    error: (message: string) => toast({
      title: "Error",
      description: message,
      variant: "destructive",
      duration: 5000,
    }),
    // ... other variants
  };
}

Accessibility

  • ARIA live regions for screen reader announcements
  • Role="alert" for error messages
  • Keyboard dismiss with Escape key
  • Focus management when dismissed

Acceptance Criteria

  • All toast variants display with correct styling
  • Auto-dismiss timers work as specified
  • Manual dismiss button functions
  • Toast queue limits to 3 visible toasts
  • Smooth enter/exit animations
  • Mobile swipe to dismiss works
  • Screen reader announcements work
  • No sensitive data in any toast messages
  • Loading toasts dismiss when action completes
  • Dark mode styling works correctly

Technical Notes

  • Use shadcn/ui toast component as base
  • Implement custom useGhostToast hook for consistent usage
  • Use React Portal for rendering outside component tree
  • Test with VoiceOver/NVDA for accessibility
  • Ensure toasts don't block user interaction
  • Consider using Radix UI Toast primitive

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature implementationpriority: mediumNormal priorityuiUser interface and components

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions