diff --git a/apps/sim/app/(landing)/components/collaboration/collaboration.tsx b/apps/sim/app/(landing)/components/collaboration/collaboration.tsx index d7b8cff120..11e912d975 100644 --- a/apps/sim/app/(landing)/components/collaboration/collaboration.tsx +++ b/apps/sim/app/(landing)/components/collaboration/collaboration.tsx @@ -7,8 +7,9 @@ import Link from 'next/link' import { Badge } from '@/components/emcn' import { trackLandingCta } from '@/app/(landing)/landing-analytics' -const AuthModal = dynamic(() => - import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal) +const AuthModal = dynamic( + () => import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal), + { loading: () => null } ) interface DotGridProps { diff --git a/apps/sim/app/(landing)/components/features/features.tsx b/apps/sim/app/(landing)/components/features/features.tsx index f9ab0d6d6c..e1395305e7 100644 --- a/apps/sim/app/(landing)/components/features/features.tsx +++ b/apps/sim/app/(landing)/components/features/features.tsx @@ -8,8 +8,9 @@ import { Badge } from '@/components/emcn' import { FeaturesPreview } from '@/app/(landing)/components/features/components/features-preview' import { trackLandingCta } from '@/app/(landing)/landing-analytics' -const AuthModal = dynamic(() => - import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal) +const AuthModal = dynamic( + () => import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal), + { loading: () => null } ) function hexToRgba(hex: string, alpha: number): string { diff --git a/apps/sim/app/(landing)/components/footer/footer-cta.tsx b/apps/sim/app/(landing)/components/footer/footer-cta.tsx index ff98ff7e15..3ec991880d 100644 --- a/apps/sim/app/(landing)/components/footer/footer-cta.tsx +++ b/apps/sim/app/(landing)/components/footer/footer-cta.tsx @@ -9,8 +9,9 @@ import { useLandingSubmit } from '@/app/(landing)/components/landing-preview/com import { trackLandingCta } from '@/app/(landing)/landing-analytics' import { useAnimatedPlaceholder } from '@/hooks/use-animated-placeholder' -const AuthModal = dynamic(() => - import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal) +const AuthModal = dynamic( + () => import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal), + { loading: () => null } ) const MAX_HEIGHT = 120 diff --git a/apps/sim/app/(landing)/components/hero/hero.tsx b/apps/sim/app/(landing)/components/hero/hero.tsx index 62b62b4e73..dc1343149b 100644 --- a/apps/sim/app/(landing)/components/hero/hero.tsx +++ b/apps/sim/app/(landing)/components/hero/hero.tsx @@ -4,14 +4,17 @@ import dynamic from 'next/dynamic' import { cn } from '@/lib/core/utils/cn' import { trackLandingCta } from '@/app/(landing)/landing-analytics' -const AuthModal = dynamic(() => - import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal) +const AuthModal = dynamic( + () => import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal), + { loading: () => null } ) -const DemoRequestModal = dynamic(() => - import('@/app/(landing)/components/demo-request/demo-request-modal').then( - (m) => m.DemoRequestModal - ) +const DemoRequestModal = dynamic( + () => + import('@/app/(landing)/components/demo-request/demo-request-modal').then( + (m) => m.DemoRequestModal + ), + { loading: () => null } ) const LandingPreview = dynamic( diff --git a/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-panel/landing-preview-panel.tsx b/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-panel/landing-preview-panel.tsx index 94e39cb27b..5e77354fc8 100644 --- a/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-panel/landing-preview-panel.tsx +++ b/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-panel/landing-preview-panel.tsx @@ -21,8 +21,9 @@ import { } from '@/app/(landing)/components/landing-preview/components/landing-preview-workflow/workflow-data' import { trackLandingCta } from '@/app/(landing)/landing-analytics' -const AuthModal = dynamic(() => - import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal) +const AuthModal = dynamic( + () => import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal), + { loading: () => null } ) type PanelTab = 'copilot' | 'editor' diff --git a/apps/sim/app/(landing)/components/navbar/navbar.tsx b/apps/sim/app/(landing)/components/navbar/navbar.tsx index da1e114f07..4ee2fdb2ac 100644 --- a/apps/sim/app/(landing)/components/navbar/navbar.tsx +++ b/apps/sim/app/(landing)/components/navbar/navbar.tsx @@ -17,8 +17,9 @@ import { GitHubStars } from '@/app/(landing)/components/navbar/components/github import { trackLandingCta } from '@/app/(landing)/landing-analytics' import { getBrandConfig } from '@/ee/whitelabeling' -const AuthModal = dynamic(() => - import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal) +const AuthModal = dynamic( + () => import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal), + { loading: () => null } ) type DropdownId = 'docs' | 'blog' | null diff --git a/apps/sim/app/(landing)/components/pricing/pricing.tsx b/apps/sim/app/(landing)/components/pricing/pricing.tsx index 3150e7213a..48a1bf4dd8 100644 --- a/apps/sim/app/(landing)/components/pricing/pricing.tsx +++ b/apps/sim/app/(landing)/components/pricing/pricing.tsx @@ -4,14 +4,17 @@ import dynamic from 'next/dynamic' import { Badge } from '@/components/emcn' import { trackLandingCta } from '@/app/(landing)/landing-analytics' -const AuthModal = dynamic(() => - import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal) +const AuthModal = dynamic( + () => import('@/app/(landing)/components/auth-modal/auth-modal').then((m) => m.AuthModal), + { loading: () => null } ) -const DemoRequestModal = dynamic(() => - import('@/app/(landing)/components/demo-request/demo-request-modal').then( - (m) => m.DemoRequestModal - ) +const DemoRequestModal = dynamic( + () => + import('@/app/(landing)/components/demo-request/demo-request-modal').then( + (m) => m.DemoRequestModal + ), + { loading: () => null } ) interface PricingTier { diff --git a/apps/sim/app/_shell/providers/session-provider.tsx b/apps/sim/app/_shell/providers/session-provider.tsx index ecd1211d72..6d77ee79c8 100644 --- a/apps/sim/app/_shell/providers/session-provider.tsx +++ b/apps/sim/app/_shell/providers/session-provider.tsx @@ -94,6 +94,7 @@ export function SessionProvider({ children }: { children: React.ReactNode }) { }) if ( typeof posthog.startSessionRecording === 'function' && + typeof posthog.sessionRecordingStarted === 'function' && !posthog.sessionRecordingStarted() ) { posthog.startSessionRecording() diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/queued-messages/queued-messages.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/queued-messages/queued-messages.tsx index 55c0478727..0773aea4c4 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/queued-messages/queued-messages.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/queued-messages/queued-messages.tsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useRef, useState } from 'react' +import { useCallback, useRef, useState } from 'react' import { ArrowUp, ChevronDown, ChevronRight, Paperclip, Pencil, Trash2 } from 'lucide-react' import { Tooltip } from '@/components/emcn' import { UserMessageContent } from '@/app/workspace/[workspaceId]/home/components/user-message-content' @@ -17,22 +17,23 @@ interface QueuedMessagesProps { export function QueuedMessages({ messageQueue, onRemove, onSendNow, onEdit }: QueuedMessagesProps) { const [isExpanded, setIsExpanded] = useState(true) - const containerRef = useRef(null) const [isNarrow, setIsNarrow] = useState(false) + const roRef = useRef(null) - const hasMessages = messageQueue.length > 0 - - useEffect(() => { - const el = containerRef.current + const containerRef = useCallback((el: HTMLDivElement | null) => { + if (roRef.current) { + roRef.current.disconnect() + roRef.current = null + } if (!el) return const ro = new ResizeObserver((entries) => { setIsNarrow(entries[0].contentRect.width < NARROW_WIDTH_PX) }) ro.observe(el) - return () => ro.disconnect() - }, [hasMessages]) + roRef.current = ro + }, []) - if (!hasMessages) return null + if (messageQueue.length === 0) return null return (
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx index bbba6b4bd7..5e58f5ca6f 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx @@ -10,12 +10,17 @@ import { useWorkflows } from '@/hooks/queries/workflows' const USER_MESSAGE_CLASSES = 'whitespace-pre-wrap break-words [overflow-wrap:anywhere] font-[430] font-[family-name:var(--font-inter)] text-base text-[var(--text-primary)] leading-[23px] tracking-[0] antialiased' +const COMPACT_CLASSES = + 'truncate text-small leading-[20px] font-[430] font-[family-name:var(--font-inter)] text-[var(--text-primary)] tracking-[0] antialiased' + interface UserMessageContentProps { content: string contexts?: ChatMessageContext[] className?: string /** When true, render mentions as plain inline text (no icon/pill) so truncation flows naturally. */ plainMentions?: boolean + /** Use compact single-line layout with truncation. */ + compact?: boolean } function escapeRegex(str: string): string { @@ -73,15 +78,15 @@ export function UserMessageContent({ contexts, className, plainMentions = false, + compact = false, }: UserMessageContentProps) { const trimmed = content.trim() - const classes = cn(USER_MESSAGE_CLASSES, className) + const classes = cn(compact ? COMPACT_CLASSES : USER_MESSAGE_CLASSES, className) - if (!contexts || contexts.length === 0) { - return

{trimmed}

- } - - const ranges = computeMentionRanges(content, contexts) + const ranges = useMemo( + () => (contexts && contexts.length > 0 ? computeMentionRanges(content, contexts) : []), + [content, contexts] + ) if (ranges.length === 0) { return

{trimmed}