diff --git a/PRPs/adaptive-entry-content-layouts.md b/PRPs/adaptive-entry-content-layouts.md new file mode 100644 index 000000000..da04e447b --- /dev/null +++ b/PRPs/adaptive-entry-content-layouts.md @@ -0,0 +1,384 @@ +# PRP: Adaptive Entry Content Layouts for Different Media Types + +## Overview + +Transform the entry content display system from a fixed, article-centric layout to an adaptive system that renders different layouts optimized for specific media types (Social Media, Pictures, Videos, Articles). This will provide media-appropriate viewing experiences that match popular platform conventions while leveraging existing component patterns from the entry list items. + +## Current Implementation Analysis + +### Current Architecture + +- **Fixed Entry Content Layout**: `EntryContent.tsx` uses article-centric structure: Header → Title → AI Summary → Content Body → Attachments → Support Creator +- **Entry List Differentiation**: Entry list items already have adaptive layouts via `getItemComponentByView()` mapping +- **View-Type System**: `FeedViewType` enum defines Articles, SocialMedia, Pictures, Videos, Audios, Notifications +- **Template System**: GridItemTemplate and ListItemTemplate provide consistent patterns for different view types + +### Current Entry Content Structure + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/entry-content/EntryContent.tsx` + +```typescript +// Current fixed structure for all entry types +
+ + // Prominent title display + // AI-generated summary + // Main content + // File attachments + // Creator support section +
+``` + +### Existing Adaptive Patterns in Entry List Items + +#### Social Media Item Pattern (`social-media-item.tsx`) + +- **Layout**: Avatar left, content right with author name → content → media gallery +- **Content Handling**: Collapsible content with "show more", minimal title prominence +- **Media**: Adaptive gallery (horizontal vs grid based on aspect ratios) + +#### Picture Item Pattern (`picture-item.tsx`) + +- **Layout**: Image carousel with footer metadata +- **Media**: SwipeMedia component for multiple images, masonry layout support +- **Content**: Author info and metadata in footer + +#### Video Item Pattern (`video-item.tsx`) + +- **Layout**: Video player/thumbnail → author/title → description +- **Media**: Preview on hover, modal video player, duration overlay +- **Content**: Title and description below video + +### Current Limitations + +1. **EntryContent ignores view type**: All entries use identical article layout regardless of `feedViewType` +2. **Poor UX for non-article content**: Social media posts show unnecessary titles, videos buried in text +3. **Unused adaptive patterns**: Entry list items have perfect media layouts that aren't leveraged in content view +4. **Inconsistent experience**: Different UX between entry list (adaptive) and entry content (fixed) + +## Proposed Solution + +### Architecture Changes + +Create an adaptive entry content system that selects appropriate layout components based on `FeedViewType`, leveraging existing patterns from entry list items while optimizing for full content display. + +### Component Factory Pattern + +Use factory pattern to dynamically select layout components: + +```typescript +const EntryContentLayoutFactory = { + [FeedViewType.Articles]: ArticleLayout, + [FeedViewType.SocialMedia]: SocialMediaLayout, + [FeedViewType.Pictures]: PicturesLayout, + [FeedViewType.Videos]: VideosLayout, + [FeedViewType.Audios]: AudioLayout, + [FeedViewType.Notifications]: ArticleLayout, // fallback +} +``` + +### Layout-Specific Components + +#### 1. SocialMediaLayout + +**Pattern**: Based on `social-media-item.tsx` but optimized for full content view + +```typescript +// Layout: Avatar + Author Info + Content + Media Gallery +
+ {/* Author avatar */} +
+ {/* Author name, handle, timestamp */} + {/* Social media content */} + {/* Adaptive image/video gallery */} + {/* AI summary if available */} +
+
+``` + +#### 2. PicturesLayout + +**Pattern**: Based on `picture-item.tsx` and `PreviewMediaContent.tsx` + +```typescript +// Layout: Image Carousel + Sidebar with metadata +
+
{/* Image area */} + +
+
{/* Sidebar */} + + + + +
+
+``` + +#### 3. VideosLayout + +**Pattern**: Based on `video-item.tsx` but full-sized + +```typescript +// Layout: Video Player + Title/Description below +
+
{/* Video area */} + +
+
{/* Content area */} + + + + +
+
+``` + +#### 4. ArticleLayout (Current) + +**Pattern**: Keep existing layout for articles + +```typescript +// Current article structure preserved + + + + + + +``` + +## Implementation Tasks + +### Phase 1: Core Architecture Setup + +#### 1. Create Layout Factory System + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/factory.ts` + +```typescript +export const getEntryContentLayout = (viewType: FeedViewType) => { + return EntryContentLayoutFactory[viewType] || ArticleLayout +} +``` + +#### 2. Create Base Layout Components + +**Files**: + +- `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/SocialMediaLayout.tsx` +- `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/PicturesLayout.tsx` +- `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/VideosLayout.tsx` +- `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/ArticleLayout.tsx` + +#### 3. Update EntryContent Component + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/entry-content/EntryContent.tsx` + +```typescript +// Replace fixed layout with factory-based selection +const LayoutComponent = getEntryContentLayout(entry.feedViewType) +return +``` + +### Phase 2: Layout Implementation + +#### 4. Implement SocialMediaLayout + +- Extract author display logic from `social-media-item.tsx` +- Implement adaptive media gallery +- Handle collapsible content with proper full-view sizing +- Reference: Twitter-like layout patterns + +#### 5. Implement PicturesLayout + +- Integrate `SwipeMedia` component for image carousel +- Create sidebar layout for metadata +- Handle single vs multiple images +- Reference: Instagram-like layout patterns + +#### 6. Implement VideosLayout + +- Integrate video player functionality from `video-item.tsx` +- Add video controls and duration display +- Layout title/description below video +- Reference: YouTube-like layout patterns + +#### 7. Extract ArticleLayout + +- Move current `EntryContent` structure to dedicated `ArticleLayout` +- Ensure no regression in article viewing experience + +### Phase 3: Shared Components + +#### 8. Create Shared UI Components + +- `AuthorHeader`: Consistent author display (avatar, name, timestamp) +- `ContentBody`: Adaptive content rendering with markdown support +- `MediaGallery`: Reusable media gallery component +- `VideoPlayer`: Consistent video player wrapper + +#### 9. Update Entry Context Provider + +- Ensure entry context includes `feedViewType` information +- Add layout-specific metadata handling + +### Phase 4: Testing & Polish + +#### 10. Responsive Design Implementation + +- Mobile layouts for each media type +- Tablet adaptations +- Handle edge cases (missing media, long content) + +#### 11. Animation & Transitions + +- Smooth layout transitions when switching between entries +- Media loading states and placeholders +- Maintain existing animation patterns + +## Context & References + +### Existing Codebase Patterns + +- **Entry List Items**: `apps/desktop/layer/renderer/src/modules/entry-column/Items/` - Perfect reference patterns +- **Media Components**: `SwipeMedia`, `PreviewMediaContent`, `Media` - Reusable media handling +- **Template System**: `GridItemTemplate` - Consistent footer patterns +- **View Type System**: `getItemComponentByView()` - Proven factory pattern implementation + +### External Documentation & Best Practices + +- **Factory Pattern**: https://dev.to/moayad523/stop-using-conditional-rendering-leveraging-the-factory-pattern-for-dynamic-component-creation-740 +- **React Conditional Rendering**: https://react.dev/learn/conditional-rendering +- **Switch Pattern**: https://dev.to/musatov/conditional-rendering-in-react-with-a-switch-component-23ph +- **Social Media Layouts**: https://github.com/thisisadityarao/react-social-media-cards +- **Instagram Layout Patterns**: https://github.com/natividadesusana/instagram-layout-react +- **Adaptive Design**: https://www.interaction-design.org/literature/topics/adaptive-design +- **React Social Media Embed**: https://www.npmjs.com/package/react-social-media-embed + +### UI Reference Platforms + +- **Social Media**: Twitter's post layout with avatar, author info, and content +- **Pictures**: Instagram's image carousel with sidebar metadata +- **Videos**: YouTube's video player with title/description below +- **Articles**: Current Follow article layout (preserve existing UX) + +## Validation Gates + +### Code Quality + +```bash +# TypeScript validation +pnpm run typecheck + +# Linting +pnpm run lint:tsl +pnpm run lint + +# Format validation +pnpm run format + +# Build validation +pnpm run build:web +``` + +### Functional Testing + +```bash +# Manual testing checklist +1. Social Media entries → Avatar left, content right, proper media gallery +2. Picture entries → Image carousel + sidebar metadata, multiple image handling +3. Video entries → Video player + title/description below, controls work +4. Article entries → No regression, identical to current layout +5. Mixed feed → Layout switches appropriately between entry types +6. Mobile responsive → All layouts adapt properly to mobile screens +7. Media loading → Proper loading states and error handling +``` + +### Performance Validation + +- Bundle size impact analysis (should be minimal due to code splitting) +- Layout shift measurement (should be zero) +- Media loading performance maintained +- Memory usage with multiple media types + +## Success Criteria + +- [ ] Social media entries display with Twitter-like layout (avatar + author + content) +- [ ] Picture entries display with Instagram-like layout (carousel + sidebar) +- [ ] Video entries display with YouTube-like layout (player + title below) +- [ ] Article entries maintain identical current layout +- [ ] Factory pattern correctly selects layout based on `FeedViewType` +- [ ] All existing functionality preserved (AI summary, attachments, etc.) +- [ ] Mobile responsive design works across all layouts +- [ ] No performance regression in entry switching +- [ ] No bundle size increase over 5% +- [ ] All media loading states properly handled + +## Risk Mitigation + +### Potential Issues + +1. **Layout Complexity**: Different layouts might conflict with existing entry content container sizing +2. **Media Loading**: Complex media components might impact performance +3. **Mobile Responsiveness**: Desktop-optimized layouts might break on mobile +4. **Bundle Size**: Adding multiple layout components could increase bundle size +5. **Component Dependencies**: Shared components might have circular dependencies + +### Mitigation Strategies + +1. **Container Isolation**: Use CSS containment and absolute positioning where needed +2. **Lazy Loading**: Implement code splitting for layout components +3. **Mobile-First**: Design mobile layouts first, then enhance for desktop +4. **Bundle Analysis**: Use webpack-bundle-analyzer to monitor size impact +5. **Dependency Management**: Clear component hierarchy and shared utilities in separate files + +### Rollback Strategy + +- Feature flag implementation to toggle between old and new layouts +- Gradual rollout by `FeedViewType` (start with least-used types) +- Database flag to disable adaptive layouts per user preference + +## Additional Considerations + +### Accessibility + +- Ensure all layouts maintain proper heading hierarchy +- Video players must support keyboard navigation +- Image carousels need proper ARIA labels +- Screen reader compatibility across all layouts + +### i18n Support + +- All new text elements properly localized +- Layout adjustments for RTL languages +- Consistent translation keys across layouts + +### Future Extensibility + +- Audio layout placeholder implementation +- Plugin system for custom layout types +- Theme system integration for layout variants + +## Confidence Score: 9/10 + +This PRP provides a comprehensive implementation approach with: + +- ✅ **Detailed codebase analysis**: Complete understanding of existing patterns and architecture +- ✅ **Proven patterns**: Leveraging successful entry list item layouts +- ✅ **Factory pattern**: Clean, extensible architecture for layout selection +- ✅ **External research**: Best practices from social media layout implementations +- ✅ **Existing components**: Reusing proven media handling components +- ✅ **Clear implementation path**: Phased approach with specific file references +- ✅ **Risk mitigation**: Identified potential issues with concrete solutions +- ✅ **Executable validation**: Specific testing steps and success criteria + +High confidence is justified because: + +1. **Existing foundation**: Entry list items already demonstrate successful adaptive patterns +2. **Component reuse**: Media components (`SwipeMedia`, `PreviewMediaContent`) are proven +3. **Clear architecture**: Factory pattern is well-established in the codebase +4. **External validation**: Research confirms best practices align with proposed approach +5. **Minimal breaking changes**: Articles maintain existing layout, reducing regression risk + +The main implementation involves connecting existing successful patterns rather than building entirely new systems, significantly reducing complexity and risk. diff --git a/PRPs/adaptive-entry-layouts-fixes.md b/PRPs/adaptive-entry-layouts-fixes.md new file mode 100644 index 000000000..5efef6b4c --- /dev/null +++ b/PRPs/adaptive-entry-layouts-fixes.md @@ -0,0 +1,530 @@ +# PRP: Fix Adaptive Entry Content Layout Issues + +## Overview + +Fix specific layout and functionality issues in the existing adaptive entry content layouts implemented in `PRPs/adaptive-entry-content-layouts.md`. The adaptive layouts are working but have implementation issues that affect user experience across Social Media, Pictures, and Videos layouts. + +## Current Issues Analysis + +### Current Implementation Status + +The adaptive layout factory system is successfully implemented: + +- **Factory System**: `getEntryContentLayout()` in `layouts/factory.ts` correctly routes to layout-specific components +- **Layout Components**: SocialMediaLayout, PicturesLayout, VideosLayout, ArticleLayout are created +- **Integration**: `AdaptiveContentRenderer` in `EntryContent.tsx` properly uses the factory pattern + +### Specific Issues Identified + +#### 1. Social Media Layout Issues + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/SocialMediaLayout.tsx` + +**Problem 1**: Duplicate Author Display + +- Lines 47-54: Shows `AuthorHeader` with avatar (48px size) +- Lines 58-62: Shows another `AuthorHeader` without avatar +- **Result**: Author name appears twice in the layout + +**Problem 2**: Show More Button Logic Still Present + +- Lines 40-42: Uses `autoExpandLongSocialMedia` setting to conditionally show `CollapsedSocialMediaItem` +- Lines 96-143: `CollapsedSocialMediaItem` implements "show more" button with LRU cache +- **User Request**: Remove this logic entirely and force full display + +**Problem 3**: AI Summary Position + +- Line 87: `` is at the bottom of the content +- **User Request**: Move AI summary to the top of the layout + +#### 2. Pictures Layout Issues + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/PicturesLayout.tsx` + +**Problem**: Mixed Media and Text Content + +- Current implementation uses `SwipeMedia` for carousel but doesn't follow "PreviewMediaContent logic" +- Text content mixed with multimedia content +- **User Request**: Separate multimedia content (using PreviewMediaContent) from text content + +#### 3. Videos Layout Issues + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/VideosLayout.tsx` + +**Problem 1**: VideoPlayer Using Mini Player + +- VideoPlayer component (`shared/VideoPlayer.tsx` lines 56-71) creates both `miniIframeSrc` and `iframeSrc` +- Lines 129-133: Uses `miniIframeSrc` for preview/hover (optimized for small sizes) +- **User Request**: Use `iframeSrc` directly for better large-screen experience + +**Problem 2**: Content Duplication + +- `ContentBody` component (lines 61-66) renders with `noMedia={false}` by default +- This includes images/iframes in text content that duplicate what's shown in video player +- **User Request**: Remove multimedia elements from text content, show only text + +## Proposed Solutions + +### 1. Social Media Layout Fixes + +#### 1.1 Fix Duplicate Author Display + +Remove the separate avatar display and use single AuthorHeader with proper positioning: + +```typescript +// Current problematic structure (lines 45-62): +
+ {/* Avatar */} +
+ +
+ {/* Content */} +
+ + // ... rest of content +
+
+ +// Fixed structure - single author header: +
+ +
+ + // ... content follows +
+
+``` + +#### 1.2 Remove Show More Logic + +Replace conditional wrapper with direct content display: + +```typescript +// Remove lines 40-42 autoExpandLongSocialMedia logic +// Remove lines 96-143 CollapsedSocialMediaItem component entirely + +// Replace EntryContentWrapper usage (lines 66-73) with direct ContentBody: + +``` + +#### 1.3 Move AI Summary to Top + +Reorder components to show AI Summary after author header: + +```typescript +
+ + {/* Move to top */} + + +
+``` + +### 2. Pictures Layout Fixes + +#### 2.1 Implement PreviewMediaContent Pattern + +Replace current SwipeMedia carousel with PreviewMediaContent for better multimedia handling: + +```typescript +// Current implementation uses SwipeMedia (lines 52-61) +// Replace with PreviewMediaContent pattern: + +import { usePreviewMedia } from "~/components/ui/media/hooks" + +const PicturesLayout: React.FC = ({ entryId, ... }) => { + const entry = useEntry(entryId, (state) => ({ media: state.media, content: state.content })) + + const textContent = useMemo(() => ( +
+ {/* Text only */} + +
+ ), [entryId, ...]) + + const previewMedia = usePreviewMedia(textContent) + + return ( +
+
+ {entryMedia.length > 0 ? ( + + ) : ( +
No media content
+ )} +
+ +
+
+ +
+
+ + {textContent} {/* Separated text content */} +
+
+
+ ) +} +``` + +### 3. Videos Layout Fixes + +#### 3.1 Use Full-Size iframe Instead of Mini Player + +Modify VideoPlayer to use `iframeSrc` directly for large-screen optimization: + +```typescript +// In VideosLayout.tsx, pass preferFullSize prop to VideoPlayer: + + +// In shared/VideoPlayer.tsx, modify to respect preferFullSize: +export const VideoPlayer: React.FC = ({ + preferFullSize = false, + ...props +}) => { + const displaySrc = preferFullSize ? iframeSrc : miniIframeSrc + + return ( +
+ {displaySrc ? ( + + ) : ( + // Fallback to media preview + )} +
+ ) +} +``` + +#### 3.2 Filter Media from Text Content + +Create text-only version of ContentBody by adding `noMedia` prop: + +```typescript +// In VideosLayout.tsx (lines 61-66), add noMedia={true}: + + +// ContentBody.tsx already supports noMedia prop (line 49) +// This will filter out multimedia elements from HTML content +``` + +## Implementation Tasks + +### Phase 1: Social Media Layout Fixes + +#### Task 1.1: Fix Duplicate Author Headers + +**File**: `SocialMediaLayout.tsx` + +- Remove duplicate AuthorHeader components (lines 47-54 and 58-62) +- Use single FeedIcon + AuthorHeader pattern from original social-media-item.tsx +- Maintain proper spacing and styling + +#### Task 1.2: Remove Show More Logic + +**File**: `SocialMediaLayout.tsx` + +- Remove `autoExpandLongSocialMedia` usage (lines 40-42) +- Delete `CollapsedSocialMediaItem` component entirely (lines 96-143) +- Replace `EntryContentWrapper` with direct `ContentBody` usage + +#### Task 1.3: Reorder AI Summary Position + +**File**: `SocialMediaLayout.tsx` + +- Move `` from line 87 to after AuthorHeader +- Add appropriate spacing and styling for top position + +### Phase 2: Pictures Layout Enhancement + +#### Task 2.1: Implement PreviewMediaContent Integration + +**File**: `PicturesLayout.tsx` + +- Import and use `usePreviewMedia` hook +- Replace SwipeMedia carousel with clickable preview that opens PreviewMediaContent modal +- Separate multimedia and text content rendering + +### Phase 3: Videos Layout Enhancement + +#### Task 3.1: Update VideoPlayer for Large Screen + +**File**: `shared/VideoPlayer.tsx` + +- Add `preferFullSize` prop to use `iframeSrc` instead of `miniIframeSrc` +- Implement proper responsive design for large screens + +#### Task 3.2: Filter Text Content + +**File**: `VideosLayout.tsx` + +- Update ContentBody usage to include `noMedia={true}` prop +- Ensure multimedia elements are filtered from text display + +### Phase 4: Testing and Validation + +#### Task 4.1: Layout Validation + +- Test each layout with various entry types +- Verify author information displays correctly +- Confirm media handling works as expected +- Test responsive behavior on different screen sizes + +#### Task 4.2: Integration Testing + +- Verify factory pattern still routes correctly +- Test layout switching between different entry types +- Confirm no regressions in ArticleLayout + +## Context & References + +### Existing Codebase Components + +#### Key Files to Modify + +- `SocialMediaLayout.tsx` - Main fixes for duplicate author and show more logic +- `PicturesLayout.tsx` - PreviewMediaContent integration +- `VideosLayout.tsx` - Full-size iframe and text filtering +- `shared/VideoPlayer.tsx` - preferFullSize prop support +- `shared/ContentBody.tsx` - Already supports noMedia prop + +#### Key Files to Reference + +- `social-media-item.tsx` - Original social media layout pattern (single author header) +- `PreviewMediaContent.tsx` - Modal-based media preview with sidebar support +- `AuthorHeader.tsx` - Shared author display component +- `MediaGallery.tsx` - Media display patterns + +### External Best Practices + +#### Responsive iframe Guidelines + +- **Modern CSS Approach**: Use `aspect-ratio: 16/9` for responsive video containers +- **Large Screen Optimization**: Implement max-width constraints to prevent oversized displays +- **Performance**: Use appropriate iframe sources based on screen size and context + +**Reference**: https://blog.logrocket.com/best-practices-react-iframes/ +**Reference**: https://cloudinary.com/guides/video-effects/responsive-video-embedding-embed-video-iframe-size-relative-to-screen-size + +#### HTML Content Filtering + +- **Text Extraction**: Use `noMedia` flags to filter multimedia elements from HTML content +- **DOM-based Filtering**: Leverage existing HTML processing to remove specific tags +- **Content Separation**: Maintain clear separation between multimedia and text content + +**Reference**: Server-side content filtering approaches for media removal +**Reference**: https://www.bookstack.cn/read/crawl4ai-0.4-en/dcca2e8c0a744b29.md + +### UI Reference Patterns + +#### Social Media Layout + +- **Single Author Header**: Follow Twitter-like pattern with avatar + name + handle + timestamp +- **Content Flow**: Author → AI Summary → Text Content → Media Gallery +- **No Collapse Logic**: Display full content without truncation in content view + +#### Pictures Layout + +- **Modal Preview**: Use PreviewMediaContent for sophisticated media viewing +- **Sidebar Metadata**: Article-like sidebar with text content separate from media +- **Click to Preview**: Simple click interaction to open full preview modal + +#### Videos Layout + +- **Full-Size Player**: Use appropriate iframe source for screen size +- **Text-Only Content**: Filter multimedia from description to avoid duplication +- **Standard Flow**: Video Player → Title → Author → Description (text only) → AI Summary + +## Validation Gates + +### Code Quality + +```bash +# TypeScript validation +pnpm run typecheck + +# Linting validation +pnpm run lint:tsl +pnpm run lint + +# Format validation +pnpm run format + +# Build validation +pnpm run build:web +``` + +### Functional Testing Checklist + +#### Social Media Layout + +- [ ] Author name appears only once (not duplicated) +- [ ] Author header shows avatar, name, handle (if Twitter), and timestamp +- [ ] AI summary appears at the top, below author header +- [ ] Content displays in full without "show more" button +- [ ] Media gallery displays correctly below content +- [ ] Layout matches original social-media-item.tsx patterns + +#### Pictures Layout + +- [ ] Multimedia content separated from text content +- [ ] Clicking images opens PreviewMediaContent modal +- [ ] Sidebar displays text content with proper overflow handling +- [ ] Author header displays in sidebar +- [ ] AI summary appears in sidebar text content area + +#### Videos Layout + +- [ ] Video player uses full-size iframe (not mini version) +- [ ] Video player displays properly at large screen sizes +- [ ] Text content below video contains no duplicate images/media +- [ ] Author information displays below video +- [ ] AI summary appears at bottom of text content + +### Performance Validation + +- [ ] No layout shift when switching between entry types +- [ ] Video iframe loads appropriately for screen size +- [ ] PreviewMediaContent modal opens smoothly +- [ ] Text content filtering doesn't impact render performance +- [ ] No memory leaks with modal-based media preview + +### Responsive Design + +- [ ] All layouts adapt properly to mobile screens +- [ ] Video player maintains aspect ratio across screen sizes +- [ ] Pictures sidebar stacks properly on narrow screens +- [ ] Social media layout remains readable on all devices + +## Success Criteria + +### Primary Objectives + +- [ ] **Social Media**: Single author header, AI summary at top, no show more button +- [ ] **Pictures**: PreviewMediaContent integration, separated multimedia/text content +- [ ] **Videos**: Full-size iframe player, text-only content descriptions +- [ ] **All Layouts**: Maintain existing functionality while fixing specific issues + +### Quality Standards + +- [ ] Zero regression in ArticleLayout functionality +- [ ] Factory pattern continues to work seamlessly +- [ ] All existing media handling features preserved +- [ ] Mobile responsive design maintained across layouts +- [ ] Performance impact minimal (under 5% bundle increase) + +### User Experience Goals + +- [ ] Cleaner social media content display without duplication +- [ ] Better large-screen video viewing experience +- [ ] Sophisticated image preview with PreviewMediaContent modal +- [ ] Consistent author information display patterns +- [ ] Improved content organization with AI summaries positioned logically + +## Risk Mitigation + +### Potential Issues + +#### Component Dependencies + +**Risk**: Changes to shared components (VideoPlayer, ContentBody) could affect other areas +**Mitigation**: + +- Add new props with default values to maintain backward compatibility +- Test all existing entry list item displays +- Use feature flags if needed for gradual rollout + +#### PreviewMediaContent Integration + +**Risk**: Modal-based media preview might conflict with existing modal systems +**Mitigation**: + +- Test modal stacking behavior thoroughly +- Ensure proper cleanup of modal state +- Verify keyboard navigation continues to work + +#### Performance Impact + +**Risk**: Additional modal components and media filtering might impact performance +**Mitigation**: + +- Implement lazy loading for PreviewMediaContent modal +- Use React.memo for expensive components +- Profile render performance before and after changes + +### Rollback Strategy + +- Maintain existing layout components as backup +- Use git feature branches for each layout fix +- Implement progressive enhancement approach +- Test each layout individually before combining changes + +## Additional Considerations + +### Accessibility + +- Ensure all interactive elements have proper ARIA labels +- Maintain keyboard navigation for new modal interactions +- Preserve screen reader compatibility for author headers +- Test video player controls with assistive technologies + +### i18n Support + +- All new text elements properly localized +- Layout adjustments tested with longer text languages +- RTL language support maintained +- Consistent translation keys across layout components + +### Future Extensibility + +- Pattern established for other media types (Audio layout) +- Plugin system compatibility maintained +- Theme system integration preserved +- Component reusability across different layout contexts + +## Confidence Score: 9/10 + +This PRP provides a comprehensive fix approach with: + +- ✅ **Specific Issue Analysis**: Detailed examination of exact problems and file locations +- ✅ **Targeted Solutions**: Precise fixes for each identified issue without over-engineering +- ✅ **Existing Pattern Leverage**: Uses proven components and patterns already in codebase +- ✅ **External Research**: Incorporates best practices for responsive video and content filtering +- ✅ **Implementation Roadmap**: Clear phase-based approach with specific file changes +- ✅ **Risk Management**: Identified potential issues with concrete mitigation strategies +- ✅ **Comprehensive Testing**: Detailed validation gates and success criteria +- ✅ **Backward Compatibility**: Maintains existing functionality while implementing fixes + +High confidence because: + +1. **Focused Scope**: Addresses specific reported issues without unnecessary system changes +2. **Proven Components**: Leverages existing PreviewMediaContent, AuthorHeader, and ContentBody components +3. **Pattern Following**: Mimics successful patterns from social-media-item.tsx and other working components +4. **External Validation**: Research confirms best practices for responsive video and content filtering +5. **Minimal Risk**: Changes are contained to specific layout files with clear rollback options + +The implementation primarily involves connecting existing working components in better ways rather than building new complex systems, significantly reducing implementation complexity and risk. diff --git a/PRPs/ai-summary-chat-integration.md b/PRPs/ai-summary-chat-integration.md new file mode 100644 index 000000000..43d10cc90 --- /dev/null +++ b/PRPs/ai-summary-chat-integration.md @@ -0,0 +1,735 @@ +# PRP: AI Summary Chat Integration for Enhanced User Engagement + +## Overview + +Transform the AI chat interface from a static welcome screen to a context-aware, engagement-focused experience by integrating AI summary as initial content. This enhancement automatically displays relevant entry summaries when users open the AI chat panel, providing zero-friction conversation starters and increasing AI feature adoption through progressive disclosure patterns. + +## Current Implementation Analysis + +### Current Chat Interface Architecture + +**File**: `apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInterface.tsx` + +**Current Flow**: + +```typescript +// Conditional rendering based on message state +{!hasMessages && !isLoadingHistory ? ( + +) : ( + + + {(status === "submitted" || status === "streaming") && } + +)} +``` + +**WelcomeScreen Structure** (`WelcomeScreen.tsx`): + +```typescript +// Current static welcome screen +
+
+
+ // 3D AI model +

{APP_NAME} AI

// Title +

{t("welcome_description")}

// Description +
+
// Empty space +
+ {enabledShortcuts.map(...)} // Quick action shortcuts + {DEFAULT_SHORTCUTS.map(...)} // Default suggestions +
+
+
+``` + +### Existing AI Summary System + +**Summary Store** (`packages/internal/store/src/modules/summary/store.ts`): + +- **Data Structure**: `Record>` +- **Generation**: `summarySyncService.generateSummary()` with API integration +- **Hooks**: `useSummary()`, `usePrefetchSummary()`, `useSummaryStatus()` +- **Caching**: LRU cleanup with `lastAccessed` tracking + +**Visual AISummary Component** (`apps/desktop/layer/renderer/src/modules/entry-content/AISummary.tsx`): + +```typescript +// Beautiful glass-morphism design with animations +
+
+
+
+ +
+ + {t("entry_content.ai_summary")} + +
+ {summary.data && } +
+ + {summary.isLoading ? : {summary.data}} + +
+``` + +### Entry Context Integration + +**Already Implemented** (`EntryContent.ai.tsx` lines 89-98): + +```typescript +const { addOrUpdateBlock, removeBlock } = useBlockActions() +useEffect(() => { + addOrUpdateBlock({ + id: BlockSliceAction.SPECIAL_TYPES.mainEntry, + type: "mainEntry", + value: entryId, + }) + return () => { + removeBlock(BlockSliceAction.SPECIAL_TYPES.mainEntry) + } +}, [addOrUpdateBlock, entryId, removeBlock]) +``` + +**Entry Context Retrieval** (`EntryPickers.tsx` lines 15-18): + +```typescript +const mainEntryId = useAIChatStore()((s) => { + const block = s.blocks.find((b) => b.type === "mainEntry") + return block && block.type === "mainEntry" ? block.value : undefined +}) +``` + +### Current Limitations + +1. **Zero Context Awareness**: Welcome screen ignores available entry context and summary data +2. **Missed Engagement Opportunity**: Users must initiate conversation without any contextual prompts +3. **Disconnected Experience**: Rich summary data exists but isn't leveraged in chat interface +4. **Static Quick Actions**: Generic shortcuts instead of context-aware conversation starters +5. **Poor Progressive Disclosure**: No smooth transition from passive summary viewing to active conversation + +## Proposed Solution + +### Architecture Overview + +Create a context-aware chat interface that intelligently displays entry summaries as conversation starters while maintaining the existing welcome screen for non-entry contexts. The solution leverages existing summary infrastructure and visual patterns while introducing smart progressive enhancement. + +### Component Architecture + +```typescript +// Enhanced WelcomeScreen with context awareness +const WelcomeScreen = ({ onSend }: WelcomeScreenProps) => { + const mainEntryId = useMainEntryId() + const hasEntryContext = !!mainEntryId + + return ( +
+ {hasEntryContext ? ( + + ) : ( + + )} +
+ ) +} +``` + +### Core Components + +#### 1. EntrySummaryCard Component + +**File**: `apps/desktop/layer/renderer/src/modules/ai-chat/components/welcome/EntrySummaryCard.tsx` + +**Purpose**: Display entry summary with chat-optimized styling and smart actions + +```typescript +interface EntrySummaryCardProps { + entryId: string + onSend: (message: string) => void + className?: string +} + +const EntrySummaryCard: React.FC = ({ entryId, onSend, className }) => { + const actionLanguage = useActionLanguage() + const isInReadabilitySuccess = useEntryIsInReadabilitySuccess(entryId) + const summary = usePrefetchSummary({ + entryId, + target: isInReadabilitySuccess ? "readabilityContent" : "content", + actionLanguage, + enabled: true, + }) + + const quickActions = useSmartQuickActions(summary.data, entryId) + + return ( + + {/* Header with entry context */} +
+
+
+ +
+
+
+

AI Summary

+

Ready to discuss this entry

+
+
+ +
+ + {/* Summary Content */} + + {summary.isLoading ? ( + + ) : summary.data ? ( +
+ + {String(summary.data)} + +
+ ) : ( +
+ +

Summary not available

+
+ )} +
+ + {/* Smart Quick Actions */} + {summary.data && ( +
+
+ Ask about this entry +
+
+ {quickActions.map((action, index) => ( + onSend(action.prompt)} + className={cn( + "inline-flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-all", + "bg-material-medium hover:bg-material-thick", + "border border-border/50 hover:border-border", + "text-text-secondary hover:text-text", + "hover:shadow-sm active:scale-95" + )} + > + + {action.label} + + ))} +
+
+ )} + + ) +} +``` + +#### 2. Smart Quick Actions Generator + +**File**: `apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useSmartQuickActions.ts` + +**Purpose**: Generate contextual conversation starters based on summary content and entry metadata + +```typescript +interface QuickAction { + id: string + label: string + prompt: string + icon: string + priority: number +} + +export const useSmartQuickActions = ( + summaryData: string | null, + entryId: string, +): QuickAction[] => { + const entry = useEntry(entryId) + const { t } = useTranslation("ai") + + return useMemo(() => { + if (!summaryData || !entry) return DEFAULT_ENTRY_ACTIONS + + const actions: QuickAction[] = [] + + // Content-based actions + if (summaryData.length > 500) { + actions.push({ + id: "simplify", + label: t("quick_actions.simplify"), + prompt: `Can you simplify this summary in 2-3 sentences? Focus on the main points.`, + icon: "i-mgc-edit-cute-re", + priority: 1, + }) + } + + // Entry type-based actions + if (entry.url) { + actions.push({ + id: "discuss", + label: t("quick_actions.discuss"), + prompt: `What are the key insights from this article? What should I know?`, + icon: "i-mgc-chat-cute-re", + priority: 2, + }) + } + + // Always available actions + actions.push( + { + id: "questions", + label: t("quick_actions.questions"), + prompt: `What questions should I be asking about this content?`, + icon: "i-mgc-question-cute-re", + priority: 3, + }, + { + id: "takeaways", + label: t("quick_actions.takeaways"), + prompt: `What are the most important takeaways from this entry?`, + icon: "i-mgc-star-cute-re", + priority: 4, + }, + ) + + return actions.sort((a, b) => a.priority - b.priority).slice(0, 4) + }, [summaryData, entry, t]) +} + +const DEFAULT_ENTRY_ACTIONS: QuickAction[] = [ + { + id: "analyze", + label: "Analyze this entry", + prompt: "Can you analyze this entry and tell me what it's about?", + icon: "i-mgc-search-cute-re", + priority: 1, + }, + { + id: "explain", + label: "Explain key points", + prompt: "What are the key points I should understand from this entry?", + icon: "i-mgc-lightbulb-cute-re", + priority: 2, + }, +] +``` + +#### 3. Enhanced WelcomeScreen with Context Awareness + +**File**: `apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/WelcomeScreen.tsx` (Modified) + +```typescript +export const WelcomeScreen = ({ onSend }: WelcomeScreenProps) => { + const { t } = useTranslation("ai") + const aiSettings = useAISettingValue() + const mainEntryId = useMainEntryId() + const settingModalPresent = useSettingModal() + + const hasEntryContext = !!mainEntryId + const hasCustomPrompt = aiSettings.personalizePrompt?.trim() + const enabledShortcuts = aiSettings.shortcuts?.filter((shortcut) => shortcut.enabled) || [] + + return ( +
+
+ {/* Header Section - Always Present */} + +
+ +
+
+

{APP_NAME} AI

+

+ {hasEntryContext ? t("welcome_description_contextual") : t("welcome_description")} +

+
+
+ + {/* Dynamic Content Area */} +
+ + {hasEntryContext ? ( + + ) : ( + + )} + +
+ + {/* Personal Prompt - Always at Bottom if Present */} + {hasCustomPrompt && ( + settingModalPresent("ai")} + /> + )} +
+
+ ) +} +``` + +### Data Flow Integration + +#### Summary Prefetching Strategy + +```typescript +// In ChatInterface.tsx - Prefetch summary when entry context available +const ChatInterfaceContent = () => { + const hasMessages = useHasMessages() + const mainEntryId = useMainEntryId() + const actionLanguage = useActionLanguage() + + // Prefetch summary for context-aware welcome screen + usePrefetchSummary({ + entryId: mainEntryId || "", + target: "content", // Start with content, fallback to readability if needed + actionLanguage, + enabled: !!mainEntryId && !hasMessages, // Only when showing welcome screen + }) + + // ... rest of component +} +``` + +#### State Management Integration + +```typescript +// Custom hook for main entry context +export const useMainEntryId = (): string | undefined => { + return useAIChatStore()((state) => { + const block = state.blocks.find((b) => b.type === "mainEntry") + return block && block.type === "mainEntry" ? block.value : undefined + }) +} + +// Hook for entry summary in chat context +export const useEntrySummaryForChat = (entryId: string) => { + const actionLanguage = useActionLanguage() + const isInReadabilitySuccess = useEntryIsInReadabilitySuccess(entryId) + + return usePrefetchSummary({ + entryId, + target: isInReadabilitySuccess ? "readabilityContent" : "content", + actionLanguage, + enabled: !!entryId, + staleTime: 1000 * 60 * 60, // 1 hour - summaries don't change often + }) +} +``` + +### Animation and Visual Design + +#### Micro-interactions and Transitions + +```typescript +// Smooth transitions between welcome states +const welcomeVariants = { + entryContext: { + initial: { opacity: 0, y: 30, scale: 0.95 }, + animate: { opacity: 1, y: 0, scale: 1 }, + exit: { opacity: 0, y: -30, scale: 0.95 }, + }, + defaultWelcome: { + initial: { opacity: 0, y: 20, scale: 0.98 }, + animate: { opacity: 1, y: 0, scale: 1 }, + exit: { opacity: 0, y: -20, scale: 0.98 }, + }, +} + +// Quick action button animations +const quickActionVariants = { + initial: { opacity: 0, scale: 0.9, x: -10 }, + animate: { opacity: 1, scale: 1, x: 0 }, + hover: { scale: 1.02, y: -1 }, + tap: { scale: 0.98 }, +} +``` + +#### Consistent Design Language + +- **Glass-morphism**: Reuse AISummary visual patterns with chat-optimized spacing +- **Purple Gradient**: Maintain AI branding with purple accent colors +- **Spring Animations**: Use Spring.presets.smooth for all major transitions +- **Material Colors**: UIKit material colors for consistent depth and hierarchy +- **Responsive Typography**: Scalable text that works across different panel sizes + +## Implementation Plan + +### Phase 1: Core Functionality (MVP) + +#### Tasks (in order): + +1. **Create EntrySummaryCard Component** + - File: `apps/desktop/layer/renderer/src/modules/ai-chat/components/welcome/EntrySummaryCard.tsx` + - Reuse AISummary visual patterns + - Basic summary display with loading states + - Simple click-to-start conversation + +2. **Create useMainEntryId Hook** + - File: `apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useMainEntryId.ts` + - Extract mainEntry block value from AI chat store + - Handle undefined/null states gracefully + +3. **Modify WelcomeScreen Component** + - File: `apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/WelcomeScreen.tsx` + - Add conditional rendering based on entry context + - Integrate EntrySummaryCard component + - Maintain existing functionality for non-entry contexts + +4. **Add Summary Prefetching to ChatInterface** + - File: `apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatInterface.tsx` + - Prefetch summary when entry context available + - Only when welcome screen is showing (no messages) + +5. **Basic Smart Quick Actions** + - File: `apps/desktop/layer/renderer/src/modules/ai-chat/hooks/useSmartQuickActions.ts` + - Simple content-based action generation + - Default fallback actions for all entries + +6. **Update Translations** + - Add new translation keys for contextual descriptions + - Quick action labels and prompts + +### Phase 2: UX Optimization + +#### Tasks: + +7. **Enhanced Smart Quick Actions** + - Content analysis for intelligent action generation + - Entry type detection (article, social media, video) + - Priority-based action sorting + +8. **Micro-interaction Animations** + - Smooth state transitions with AnimatePresence + - Quick action button hover/tap effects + - Loading state animations with shimmer effects + +9. **Entry Quick Info Component** + - Display entry metadata (title, source, date) + - Compact design that doesn't compete with summary + - Optional component based on space constraints + +10. **Responsive Layout Adaptation** + - Floating panel vs fixed panel optimization + - Mobile-friendly touch targets + - Adaptive spacing and typography + +### Phase 3: Advanced Features + +#### Tasks: + +11. **First-time User Guidance** + - Onboarding tooltip for new feature + - Progressive disclosure of advanced features + - User preference learning + +12. **Context-aware Optimization** + - Reading progress integration + - Related entries suggestions + - Conversation history awareness + +13. **Performance Optimization** + - Summary caching improvements + - Lazy loading for non-critical components + - Bundle size optimization + +14. **A/B Testing Integration** + - Feature flag support + - Usage analytics + - Engagement metrics tracking + +## Validation Gates + +### Code Quality + +```bash +# TypeScript compilation +pnpm run typecheck + +# Linting +pnpm run lint + +# Code formatting +pnpm run format +``` + +### Testing Strategy + +```bash +# Unit tests for new hooks and components +pnpm run test apps/desktop/layer/renderer/src/modules/ai-chat + +# Integration tests for summary prefetching +pnpm run test:integration + +# E2E tests for chat interaction flows +pnpm run test:e2e -- --grep "AI Chat.*Summary" +``` + +### Manual Testing Checklist + +- [ ] **Entry Context Detection**: AI chat shows summary when viewing an entry +- [ ] **Fallback Behavior**: Default welcome screen when no entry context +- [ ] **Summary Loading**: Proper loading states and error handling +- [ ] **Quick Actions**: Context-appropriate conversation starters +- [ ] **Animations**: Smooth transitions between states +- [ ] **Responsive Design**: Works in both floating and fixed panels +- [ ] **Theme Support**: Proper light/dark mode appearance +- [ ] **Accessibility**: Keyboard navigation and screen reader support + +### Performance Metrics + +- [ ] **First Paint**: Summary content visible within 300ms +- [ ] **Bundle Impact**: <10KB addition to chat module bundle +- [ ] **Memory Usage**: No memory leaks during context switches +- [ ] **Animation Performance**: 60fps during transitions + +## Dependencies and Integration Points + +### Existing Systems Integration + +- **Summary Store**: `packages/internal/store/src/modules/summary/` +- **Entry Store**: Integration with entry context tracking +- **AI Chat Store**: Block system for entry context management +- **Translation System**: New keys for contextual content +- **Theme System**: UIKit colors and material design consistency + +### External Dependencies + +- **React Query**: Already used for summary prefetching +- **Framer Motion**: `m.` prefix components for animations +- **i18next**: Translation key expansion +- **Tailwind CSS**: UIKit color classes and material styles + +### API Integration + +- **Summary Generation**: Existing `/ai/summary` endpoint +- **No new API calls**: Reuses existing summary infrastructure +- **Caching Strategy**: Leverages existing SummaryStore LRU cache + +## Risk Assessment & Mitigation + +### Technical Risks + +1. **Performance Impact** (Low Risk) + - _Risk_: Summary prefetching could slow chat opening + - _Mitigation_: Conditional prefetching only when needed, existing cache strategy + +2. **Animation Jank** (Medium Risk) + - _Risk_: Complex animations could affect performance + - _Mitigation_: Use optimized Framer Motion patterns, test on lower-end devices + +3. **State Synchronization** (Low Risk) + - _Risk_: Entry context out of sync with chat store + - _Mitigation_: Leverage existing mainEntry block system, tested pattern + +### UX Risks + +1. **Feature Discoverability** (Medium Risk) + - _Risk_: Users may not notice the enhanced welcome screen + - _Mitigation_: Subtle onboarding hints, analytics tracking + +2. **Context Mismatch** (Low Risk) + - _Risk_: Summary doesn't match user expectations + - _Mitigation_: Clear visual hierarchy, fallback to default actions + +3. **Information Overload** (Medium Risk) + - _Risk_: Too much information in welcome screen + - _Mitigation_: Progressive disclosure, clean visual design + +## Success Metrics + +### Engagement Metrics + +- **AI Chat Adoption**: 25% increase in chat panel opens from entry context +- **Conversation Initiation**: 40% increase in messages sent from welcome screen +- **Quick Action Usage**: 60% of conversations start with context-aware quick actions +- **Session Duration**: 20% increase in average chat session length + +### Performance Metrics + +- **Load Time**: Summary content visible within 300ms +- **Error Rate**: <1% failure rate for summary loading +- **Cache Hit Rate**: >80% cache hits for recently viewed entries + +### User Satisfaction + +- **User Feedback**: Positive sentiment on enhanced chat experience +- **Feature Retention**: 70% of users who try the feature continue using it +- **Support Tickets**: No increase in AI-related support requests + +## Future Enhancements + +### Short-term (Next Quarter) + +- **Multi-language Summary Support**: Leverage existing i18n infrastructure +- **Summary Quality Feedback**: Allow users to rate summary relevance +- **Conversation Templates**: Pre-built conversation flows for common entry types + +### Medium-term (Next 6 Months) + +- **Cross-entry Conversations**: Enable discussing multiple entries in one chat +- **Smart Follow-ups**: AI-suggested next questions based on conversation context +- **Entry Annotations**: Allow highlighting specific parts of entry for discussion + +### Long-term (Next Year) + +- **Voice Interaction**: Voice commands for summary-based conversations +- **Collaborative Features**: Share AI conversations about entries +- **Advanced Analytics**: ML-driven insights on conversation patterns + +## Confidence Score: 9/10 + +This PRP provides comprehensive implementation guidance with: + +- ✅ **Detailed Architecture**: Clear component structure and data flow +- ✅ **Existing Pattern Reuse**: Leverages proven AISummary and chat patterns +- ✅ **Phased Implementation**: Incremental delivery with clear milestones +- ✅ **Risk Mitigation**: Identified potential issues with solutions +- ✅ **Testing Strategy**: Comprehensive validation approach +- ✅ **Performance Considerations**: Optimized prefetching and caching +- ✅ **UX Best Practices**: Context-aware design with progressive enhancement +- ✅ **Code Examples**: Realistic implementation snippets with proper patterns +- ✅ **Integration Points**: Clear dependencies and system boundaries +- ✅ **Success Metrics**: Measurable outcomes and validation criteria + +The implementation leverages existing, proven infrastructure while introducing meaningful enhancements that align with modern AI chat UX patterns and the application's design system. diff --git a/PRPs/entry-layouts-comprehensive-fixes.md b/PRPs/entry-layouts-comprehensive-fixes.md new file mode 100644 index 000000000..aa7024d04 --- /dev/null +++ b/PRPs/entry-layouts-comprehensive-fixes.md @@ -0,0 +1,577 @@ +# PRP: Comprehensive Entry Content Layout Fixes + +## Overview + +Fix critical issues in the adaptive entry content layouts that prevent proper EntryHeader display, cause inconsistent layout patterns, and implement unwanted popup behaviors. This PRP addresses specific problems identified with SocialMedia, Pictures, and Videos layouts while also fixing entry navigation behavior. + +## Current Issues Analysis + +### Issue Context + +Following the implementation of adaptive entry content layouts in `PRPs/adaptive-entry-content-layouts.md` and `PRPs/adaptive-entry-layouts-fixes.md`, several critical issues remain that affect user experience: + +### 1. Social Media Layout - Blank EntryHeader Issue + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/SocialMediaLayout.tsx` +**Root Cause**: EntryHeader component explicitly hides all functionality for SocialMedia view + +**Current Implementation Problem**: + +```typescript +// EntryHeader.tsx lines 72-77 - Explicitly hides actions for SocialMedia +{view !== FeedViewType.SocialMedia && ( +
+ + +
+)} +``` + +**Missing Functionality**: + +- Star/bookmark actions +- Share actions +- More actions menu (read/unread toggle, archive, etc.) +- Entry metadata display when scrolled +- Read status indicators + +**Additional Issue**: SocialMedia entries also use `
` tag instead of `NavLink` in `EntryItemWrapper.tsx:212`, preventing proper navigation. + +### 2. Pictures Layout - Wrong Layout Structure + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/PicturesLayout.tsx` + +**Current Structure**: Split-screen layout (image left, metadata sidebar right) + +```typescript +
+
{/* Image area */} +
{/* Sidebar */} +``` + +**Requested Structure**: Article-like layout (title/author top, content below) with multimedia separated from text + +### 3. Videos Layout - AI Summary Position + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/VideosLayout.tsx` + +**Current Order**: + +1. EntryTitle +2. AuthorHeader +3. ContentBody +4. AISummary ← Currently at bottom + +**Requested Order**: AI Summary should be above ContentBody (between AuthorHeader and ContentBody) + +### 4. Video Entry Popup Logic + +**File**: `apps/desktop/layer/renderer/src/modules/entry-column/Items/video-item.tsx` + +**Current Behavior**: Lines 104-126 - Click triggers modal popup instead of navigation + +```typescript +onClick={(e) => { + if (iframeSrc) { + modalStack.present({ + title: "", + content: (props) => (), + }) + } else { + previewMedia(entry.media) // Triggers video preview popup + } +}} +``` + +### 5. Picture Entry Popup Logic + +**File**: `apps/desktop/layer/renderer/src/modules/entry-column/Items/picture-item.tsx` + +**Current Behavior**: Lines 46-48 - SwipeMedia triggers preview popup + +```typescript + { + previewMedia(media, i) // Triggers picture preview popup instead of navigation + }} +/> +``` + +## Proposed Solutions + +### 1. Social Media Layout Fixes + +#### 1.1 Restore EntryHeader Functionality + +**Strategy**: Remove the SocialMedia exclusion from EntryHeader component and ensure proper integration + +**File Changes**: + +- `EntryHeader.tsx`: Remove `view !== FeedViewType.SocialMedia` condition +- `EntryItemWrapper.tsx`: Change SocialMedia from `
` to `NavLink` like other entry types +- `SocialMediaLayout.tsx`: Ensure layout works with EntryHeader display + +#### 1.2 Layout Integration Pattern + +Follow the same pattern as ArticleLayout: + +```typescript +// EntryContent.tsx integration (lines 120-127) +{!isInPeekModal && ( + +)} +// Then SocialMediaLayout renders below EntryHeader +``` + +### 2. Pictures Layout Restructuring + +#### 2.1 Change to Article-Style Layout + +**New Structure**: Title/Author on top, content below, with multimedia content separated + +```typescript +// New PicturesLayout structure +
+ {/* Title and Author Section */} +
+ + +
+ + {/* Multimedia Content Section */} +
+ +
+ + {/* Text Content Section */} +
+ + +
+
+``` + +#### 2.2 Multimedia Content Separation + +- Use `noMedia={true}` on ContentBody to remove multimedia elements from text +- Display multimedia content separately in dedicated MediaGallery section +- Maintain click-to-preview functionality via `usePreviewMedia` hook + +### 3. Videos Layout - AI Summary Position Fix + +**Simple Reordering**: Move AISummary component above ContentBody + +```typescript +// Current order in VideosLayout.tsx (lines 49-72) + + + {/* Move here - above content */} + +``` + +### 4. Remove Video Entry Popup Logic + +#### 4.1 Update Video Item Click Handler + +**File**: `video-item.tsx` +**Change**: Remove modal popup logic, allow normal entry navigation + +```typescript +// Replace current onClick handler (lines 104-126) with normal entry behavior +// Remove the modal presentation logic entirely +// Let EntryItemWrapper handle navigation naturally +``` + +#### 4.2 Preserve Video Preview in Layout + +**Note**: Users can still preview videos via the VideosLayout which shows the video player properly + +### 5. Remove Picture Entry Popup Logic + +#### 5.1 Update Picture Item OnPreview Handler + +**File**: `picture-item.tsx` +**Change**: Remove `onPreview` prop from SwipeMedia to disable popup behavior + +```typescript +// Remove onPreview prop from SwipeMedia (lines 46-48) + previewMedia(media, i)} // Remove this line + className="aspect-square w-full overflow-hidden rounded-md" +/> +``` + +#### 5.2 Maintain Preview in PicturesLayout + +**Note**: Users can still preview images via the restructured PicturesLayout with proper MediaGallery integration + +## Implementation Plan + +### Phase 1: Fix Social Media Layout EntryHeader (Priority: Critical) + +#### Task 1.1: Remove SocialMedia Exclusion from EntryHeader + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/entry-header/EntryHeader.tsx` + +```typescript +// Remove condition: view !== FeedViewType.SocialMedia +// Lines 72-77: Always show EntryHeaderActions regardless of view type +
+ + +
+``` + +#### Task 1.2: Fix SocialMedia Entry Navigation + +**File**: `apps/desktop/layer/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx` + +```typescript +// Change line 212 from: +const Link = view === FeedViewType.SocialMedia ? "article" : NavLink +// To: +const Link = NavLink // Use NavLink for all entry types including SocialMedia +``` + +#### Task 1.3: Verify SocialMediaLayout Integration + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/SocialMediaLayout.tsx` + +- Ensure layout works properly when EntryHeader is displayed above it +- Test star collection overlay positioning doesn't conflict with EntryHeader +- Verify responsive behavior with EntryHeader present + +### Phase 2: Restructure Pictures Layout (Priority: High) + +#### Task 2.1: Implement Article-Style Layout Structure + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/PicturesLayout.tsx` + +- Replace split-screen layout with vertical article-style layout +- Move title and author to top section +- Create dedicated multimedia content section with MediaGallery +- Separate text content section with `noMedia={true}` + +#### Task 2.2: Update MediaGallery Integration + +- Ensure MediaGallery component supports click-to-preview functionality +- Maintain existing `usePreviewMedia` hook integration for modal previews +- Test multiple image handling and carousel behavior + +### Phase 3: Fix Videos Layout AI Summary Position (Priority: Medium) + +#### Task 3.1: Reorder Components + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/VideosLayout.tsx` + +- Move `` from line 72 to after AuthorHeader (around line 53) +- Maintain proper spacing and styling +- Test responsive behavior and content flow + +### Phase 4: Remove Popup Logic (Priority: Medium) + +#### Task 4.1: Remove Video Entry Popup Logic + +**File**: `apps/desktop/layer/renderer/src/modules/entry-column/Items/video-item.tsx` + +- Remove or simplify onClick handler (lines 104-126) +- Remove `PreviewVideoModalContent` modal presentation logic +- Allow normal entry navigation through EntryItemWrapper + +#### Task 4.2: Remove Picture Entry Popup Logic + +**File**: `apps/desktop/layer/renderer/src/modules/entry-column/Items/picture-item.tsx` + +- Remove `onPreview` prop from SwipeMedia component (lines 46-48) +- Test that normal entry navigation still works +- Verify pictures can still be previewed through PicturesLayout + +### Phase 5: Testing and Validation (Priority: High) + +#### Task 5.1: Layout Functionality Testing + +- Test EntryHeader actions work in SocialMedia layout (star, share, more actions) +- Test Pictures layout displays properly with article-style structure +- Test Videos layout shows AI summary in correct position +- Test normal entry navigation works for all layouts + +#### Task 5.2: Integration Testing + +- Test entry factory routing still works correctly +- Test mobile responsive behavior across all layout changes +- Test no regressions in ArticleLayout functionality +- Test modal preview functionality where preserved + +## Context & References + +### Codebase Architecture Understanding + +#### Entry Content System Files + +- **Factory**: `layouts/factory.ts` - Layout component selection +- **Integration**: `EntryContent.tsx` - Main integration point with EntryHeader +- **Layouts**: Individual layout components in `layouts/` directory +- **Entry Wrapper**: `EntryItemWrapper.tsx` - Controls navigation vs article tag usage + +#### Key Components to Modify + +- **EntryHeader.tsx**: Remove SocialMedia exclusion (lines 72-77) +- **EntryItemWrapper.tsx**: Fix SocialMedia navigation (line 212) +- **SocialMediaLayout.tsx**: Verify EntryHeader integration +- **PicturesLayout.tsx**: Complete restructure to article-style layout +- **VideosLayout.tsx**: Simple component reordering +- **video-item.tsx**: Remove popup click logic +- **picture-item.tsx**: Remove SwipeMedia onPreview prop + +#### Existing Patterns to Follow + +- **ArticleLayout**: Reference for proper EntryHeader integration +- **MediaGallery**: Pattern for multimedia content display +- **EntryHeaderActions**: Component providing star, share, more actions +- **usePreviewMedia**: Hook for maintaining preview functionality where appropriate + +### External Best Practices & Documentation + +#### React Component Restructuring + +- **Conditional Rendering Removal**: https://react.dev/learn/conditional-rendering +- **Component Composition**: https://react.dev/learn/passing-props-to-a-component +- **Layout Patterns**: Clean separation of content sections for better UX + +#### Entry Navigation Patterns + +- **React Router NavLink**: https://reactrouter.com/en/main/components/nav-link +- **Navigation vs Modal UX**: Best practices for content discovery vs preview + +#### Layout Design Principles + +- **Article Layout Standards**: Title → Author → Content flow for readability +- **Multimedia Content Separation**: Clear distinction between media and text content +- **Progressive Enhancement**: Maintain preview functionality while improving base navigation + +### UI/UX Reference Standards + +#### Social Media Layout + +- **Standard Pattern**: Avatar + Author info + Actions in header area +- **Content Flow**: Header actions → AI summary → Content → Media gallery +- **Action Accessibility**: All entry actions should be consistently available + +#### Pictures Layout + +- **Article-Style Pattern**: Linear flow from title → author → multimedia → text +- **Content Separation**: Clear visual separation between media and text sections +- **Preview Enhancement**: Click-to-preview maintains advanced image viewing + +#### Videos Layout + +- **Information Hierarchy**: AI summary provides context before content consumption +- **Content Flow**: Video → Title → Author → AI Summary → Description/Content + +## Validation Gates + +### Code Quality Checks + +```bash +# TypeScript validation +pnpm run typecheck + +# Linting validation +pnpm run lint:tsl +pnpm run lint + +# Code formatting +pnpm run format + +# Build validation +pnpm run build:web +``` + +### Functional Testing Checklist + +#### Social Media Layout Validation + +- [ ] EntryHeader displays with all action buttons (star, share, more actions menu) +- [ ] Social media entries navigate properly when clicked (no article tag behavior) +- [ ] Star/bookmark functionality works correctly +- [ ] Share actions function properly +- [ ] More actions menu provides read/unread, archive, etc. options +- [ ] Entry metadata displays when scrolled +- [ ] Layout integrates properly with EntryHeader space allocation + +#### Pictures Layout Validation + +- [ ] Title displays at top of layout +- [ ] Author information displays below title +- [ ] Multimedia content displays in dedicated section +- [ ] Text content displays separately without embedded media +- [ ] AI summary appears in text content section +- [ ] MediaGallery maintains click-to-preview functionality +- [ ] Layout is responsive and readable on all screen sizes + +#### Videos Layout Validation + +- [ ] AI summary displays above main content (after AuthorHeader) +- [ ] Video player displays properly at top +- [ ] Title and author information display correctly +- [ ] Text content excludes multimedia elements (`noMedia={true}`) +- [ ] Component spacing and flow is visually appealing + +#### Entry Navigation Validation + +- [ ] Video entries navigate to content view instead of showing popup +- [ ] Picture entries navigate to content view instead of showing popup +- [ ] Normal entry clicking behavior consistent across all entry types +- [ ] Preview functionality still available within content layouts +- [ ] No regressions in other entry types (Article, Audio, Notifications) + +### Performance & Integration Testing + +- [ ] No layout shift when EntryHeader is displayed with SocialMedia layout +- [ ] Entry factory routing continues to work seamlessly +- [ ] Modal preview functionality works when explicitly triggered +- [ ] Bundle size impact minimal (layout restructuring only) +- [ ] Mobile responsive design maintained across all layouts + +## Success Criteria + +### Primary Objectives + +- [ ] **Social Media**: EntryHeader displays with all actions like other entry types +- [ ] **Pictures**: Article-style layout (title/author top, content below) with multimedia separation +- [ ] **Videos**: AI summary positioned above main content +- [ ] **Navigation**: Entry clicks navigate to content view instead of triggering popups +- [ ] **Functionality**: All existing features preserved (preview, actions, etc.) + +### Quality Standards + +- [ ] Zero regressions in existing ArticleLayout functionality +- [ ] Entry factory system continues routing correctly +- [ ] All EntryHeader actions work consistently across layouts +- [ ] Mobile responsive design maintained +- [ ] Performance impact negligible + +### User Experience Improvements + +- [ ] Consistent action availability across all entry types (star, share, etc.) +- [ ] Better content organization with proper information hierarchy +- [ ] Improved navigation flow (click to view, preview when desired) +- [ ] Cleaner content separation between multimedia and text +- [ ] Maintained advanced preview functionality where appropriate + +## Risk Assessment & Mitigation + +### High-Risk Areas + +#### 1. EntryHeader Integration Changes + +**Risk**: Removing SocialMedia exclusion might break existing layout assumptions +**Mitigation**: + +- Test thoroughly with various social media entry types +- Verify responsive behavior with EntryHeader space allocation +- Implement feature flag for gradual rollout if needed + +#### 2. Navigation Behavior Changes + +**Risk**: Changing from `
` to `NavLink` might affect performance or behavior +**Mitigation**: + +- Profile performance impact of additional NavLink components +- Test keyboard navigation and accessibility compliance +- Verify no conflicts with existing event handlers + +#### 3. Pictures Layout Restructuring + +**Risk**: Complete layout change might break existing user expectations +**Mitigation**: + +- Maintain click-to-preview functionality for advanced image viewing +- Test with various image entry types and content lengths +- Consider user feedback mechanism for layout preference + +### Medium-Risk Areas + +#### Component Dependencies + +**Risk**: Changes to shared components might affect other areas +**Mitigation**: + +- Audit all usage of modified components before changes +- Use backward-compatible prop additions where possible +- Test all entry list item displays remain functional + +#### Preview Functionality + +**Risk**: Removing popup logic might eliminate desired preview features +**Mitigation**: + +- Preserve advanced preview functionality within content layouts +- Ensure MediaGallery and video players provide equivalent experience +- Test that preview modals still work when explicitly triggered + +### Rollback Strategy + +- Implement changes incrementally by layout type +- Use git feature branches for each major change +- Maintain existing layout components as backup during transition +- Feature flag capability for reverting individual layout changes + +## Additional Considerations + +### Accessibility Standards + +- Ensure EntryHeader actions maintain proper ARIA labels and keyboard navigation +- Test screen reader compatibility with restructured layouts +- Maintain proper heading hierarchy across all layout changes +- Verify video player controls remain keyboard accessible + +### Internationalization Support + +- Test all layout changes with RTL languages +- Ensure proper text flow in restructured Pictures layout +- Verify action button layouts work with translated text +- Maintain consistent translation key usage across layouts + +### Future Extensibility + +- Pattern established for other layout types (Audio, Notifications) +- EntryHeader integration approach reusable for new layout types +- Component separation supports future customization options +- Layout factory system ready for additional media types + +## Confidence Score: 8.5/10 + +This PRP provides a comprehensive solution with high implementation confidence: + +### Strengths + +- ✅ **Root Cause Analysis**: Identified exact source of each issue with file and line references +- ✅ **Proven Patterns**: Leverages existing successful EntryHeader and ArticleLayout patterns +- ✅ **Focused Scope**: Addresses specific reported issues without unnecessary complexity +- ✅ **Detailed Implementation**: Clear file-by-file changes with code examples +- ✅ **Risk Management**: Identified potential issues with concrete mitigation strategies +- ✅ **Comprehensive Testing**: Detailed validation steps for each change +- ✅ **External Research**: Incorporates best practices for navigation and layout design + +### Implementation Confidence Factors + +1. **Clear Problem Definition**: Each issue has been thoroughly analyzed with exact file locations +2. **Existing Foundation**: EntryHeader, ArticleLayout, and navigation patterns are already proven +3. **Minimal Breaking Changes**: Most changes involve removing exclusions or simple reordering +4. **Component Reuse**: Leveraging existing tested components rather than creating new ones +5. **Incremental Approach**: Changes can be implemented and tested independently +6. **Fallback Options**: Clear rollback strategy for each component change + +### Minor Risk Factors + +- **Layout Integration**: Need to verify EntryHeader spacing works with each layout type +- **Navigation Changes**: SocialMedia routing change requires thorough cross-platform testing +- **User Experience**: Pictures layout restructuring is most significant UX change + +The high confidence score reflects that this PRP addresses well-defined issues using existing proven components and patterns, with clear implementation steps and comprehensive validation approaches. diff --git a/PRPs/entry-layouts-refinement-fixes.md b/PRPs/entry-layouts-refinement-fixes.md new file mode 100644 index 000000000..1a9bdef28 --- /dev/null +++ b/PRPs/entry-layouts-refinement-fixes.md @@ -0,0 +1,660 @@ +# PRP: Entry Content Layout Refinement Fixes + +## Overview + +Address critical styling and functionality issues in the recently implemented adaptive entry content layouts. This PRP fixes three main areas: Social Media layout typography and avatar styling, Pictures layout carousel integration, and scroll container height calculation issues that cause content truncation. + +## Current Issues Analysis + +### Issue Context + +Following the implementation of adaptive entry content layouts in previous PRPs, user feedback has identified several refinement issues that affect the visual quality and functionality of the layouts. + +### 1. Social Media Layout - Typography and Avatar Issues + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/SocialMediaLayout.tsx` + +**Issue 1.1: Author Name Text Size** + +```typescript +// Current AuthorHeader.tsx implementation (lines 64-67) +
+ + + +``` + +**Problem**: Author name uses `text-sm` (14px) which is too small for social media context where author prominence is important. + +**Issue 1.2: Avatar Border Radius Scale Mismatch** + +```typescript +// Current SocialMediaLayout.tsx (line 59) + + +// Current FeedIcon.tsx avatar styling (line 283) + +``` + +**Problem**: Avatar size increased to 48px but border radius remains `rounded-sm` (2px), creating visual inconsistency. + +### 2. Pictures Layout - Carousel Implementation Issues + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/PicturesLayout.tsx` + +**Issue 2.1: Multiple Image Display** + +```typescript +// Current MediaGallery.tsx implementation (lines 47-113) +if (isAllMediaSameRatio) { + return ( +
+ {media.map((mediaItem, i, mediaList) => { + // Multiple images displayed side by side +``` + +**Problem**: MediaGallery shows multiple images side by side instead of single image with carousel navigation. + +**Issue 2.2: Missing PreviewMediaContent Integration** +**Expected**: Single image display that opens PreviewMediaContent modal on click with carousel functionality. +**Current**: Direct MediaGallery display without modal integration. + +**Issue 2.3: Entry List Click Behavior Not Restored** +**Problem**: Previous fixes removed SwipeMedia `onPreview` prop but didn't properly restore the expected clicking behavior for entry list images. + +### 3. Scroll Container Height Calculation Issues + +**Files**: + +- `packages/internal/components/src/ui/scroll-area/ScrollArea.tsx` +- `apps/desktop/layer/renderer/src/modules/entry-content/components/entry-content/EntryContent.tsx` + +**Issue 3.1: Height Mismatch** + +```typescript +// EntryContent.tsx ScrollArea usage (lines 242-244) +rootClassName={cn( + "h-0 min-w-0 grow overflow-y-auto print:h-auto print:overflow-visible", + className, +)} +``` + +**Problem**: `h-0 grow` pattern causes height calculation issues where content extends beyond scroll container. + +**Issue 3.2: Flex Container Min-Height Problem** +**Root Cause**: Flexbox containers with implicit minimum size cause scroll containers to not properly calculate their available height. + +## Proposed Solutions + +### 1. Social Media Layout Typography and Avatar Fixes + +#### 1.1 Increase Author Name Font Size + +**Strategy**: Update AuthorHeader to use larger text size for social media context + +**Implementation**: + +```typescript +// AuthorHeader.tsx - Enhanced author name styling +
+ {/* Changed from text-sm */} + + +``` + +#### 1.2 Scale Avatar Border Radius Appropriately + +**Strategy**: Use size-responsive border radius that scales with avatar dimensions + +**Implementation**: + +```typescript +// FeedIcon.tsx - Size-based border radius +const getBorderRadius = (size: number) => { + if (size <= 24) return "rounded-sm" // 2px for small avatars + if (size <= 32) return "rounded-md" // 6px for medium avatars + if (size <= 48) return "rounded-lg" // 8px for large avatars + return "rounded-xl" // 12px for extra large avatars +} + + +``` + +### 2. Pictures Layout Single Image Carousel Implementation + +#### 2.1 Replace MediaGallery with Single Image Display + +**Strategy**: Show only the first image with click-to-carousel functionality using PreviewMediaContent + +**Implementation Pattern**: + +```typescript +// PicturesLayout.tsx - Single image with carousel +const PicturesLayout: React.FC = ({ entryId, ... }) => { + const entry = useEntry(entryId, (state) => ({ media: state.media })) + const previewMedia = usePreviewMedia() + + const handleImageClick = () => { + if (entry?.media && entry.media.length > 0) { + previewMedia( + entry.media.map(m => ({ + url: m.url, + type: m.type, + blurhash: m.blurhash, + fallbackUrl: m.preview_image_url + })), + 0 // Start at first image + ) + } + } + + return ( +
+ {/* Single image display */} + {entry?.media && entry.media.length > 0 && ( +
+
+ + {entry.media.length > 1 && ( +
+ +{entry.media.length - 1} more +
+ )} +
+
+ )} + {/* Rest of content */} +
+ ) +} +``` + +#### 2.2 Restore Entry List Image Click Behavior + +**Strategy**: Re-add proper onPreview functionality to SwipeMedia in entry list contexts + +**Implementation**: + +```typescript +// picture-item.tsx - Restore preview functionality + { + previewMedia( + media.map(m => ({ + url: m.url, + type: m.type, + blurhash: m.blurhash, + fallbackUrl: m.preview_image_url + })), + i + ) + }} +/> +``` + +### 3. Scroll Container Height Fixes + +#### 3.1 Apply Min-Height Fix to Flex Containers + +**Strategy**: Add explicit `min-height: 0` to flex containers to fix height calculation + +**Implementation**: + +```typescript +// EntryContent.tsx - Fix flex container height calculation +
{/* Add min-h-0 */} + + {children} + +
+``` + +#### 3.2 Update ScrollArea Component for Better Height Handling + +**Strategy**: Enhance ScrollArea component to handle flex container height issues + +**Implementation**: + +```typescript +// ScrollArea.tsx - Enhanced flex support +export const ScrollArea = ({ + flex, + rootClassName, + viewportClassName, + ...props +}) => { + return ( + + + div]:!flex [&>div]:!flex-col [&>div]:!min-h-0", // Add min-h-0 to flex children + viewportClassName + )} + // ... rest of props + > + {children} + + + + ) +} +``` + +## Implementation Tasks + +### Phase 1: Social Media Layout Typography and Avatar Fixes (Priority: High) + +#### Task 1.1: Update AuthorHeader Font Sizes + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/shared/AuthorHeader.tsx` + +- Change author name from `text-sm` to `text-base` for better prominence +- Ensure consistency across all AuthorHeader usages +- Test with different author name lengths + +#### Task 1.2: Implement Size-Responsive Avatar Border Radius + +**File**: `apps/desktop/layer/renderer/src/modules/feed/feed-icon/FeedIcon.tsx` + +- Create `getBorderRadius()` utility function based on avatar size +- Update AvatarImage className to use responsive border radius +- Test with different avatar sizes (20px, 32px, 48px, 64px) + +#### Task 1.3: Update SocialMediaLayout Avatar Integration + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/SocialMediaLayout.tsx` + +- Verify 48px avatar size works with new border radius +- Test visual consistency with typography changes +- Ensure proper spacing and alignment + +### Phase 2: Pictures Layout Single Image Carousel (Priority: High) + +#### Task 2.1: Replace MediaGallery with Single Image Display + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/PicturesLayout.tsx` + +- Remove MediaGallery usage +- Implement single image display with first image from media array +- Add click handler for PreviewMediaContent modal +- Add visual indicator for multiple images ("+X more" overlay) + +#### Task 2.2: Create Picture-Specific Media Component + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/layouts/shared/SingleImageDisplay.tsx` + +- Create reusable single image display component +- Include click-to-carousel functionality +- Handle edge cases (no images, single image, multiple images) +- Support different aspect ratios and sizing + +#### Task 2.3: Restore Entry List Image Click Behavior + +**File**: `apps/desktop/layer/renderer/src/modules/entry-column/Items/picture-item.tsx` + +- Re-add `onPreview` prop to SwipeMedia component +- Ensure proper media format for PreviewMediaContent +- Test clicking behavior in entry list vs content view +- Verify no conflicts with entry navigation + +### Phase 3: Scroll Container Height Fixes (Priority: Critical) + +#### Task 3.1: Apply Min-Height Fixes to Entry Content + +**File**: `apps/desktop/layer/renderer/src/modules/entry-content/components/entry-content/EntryContent.tsx` + +- Add `min-h-0` classes to flex containers +- Update ScrollArea usage to include flex height fixes +- Test with different content lengths and screen sizes +- Verify fix applies to all layout types (Social Media, Videos, Articles, Pictures) + +#### Task 3.2: Enhance ScrollArea Component + +**File**: `packages/internal/components/src/ui/scroll-area/ScrollArea.tsx` + +- Add explicit `min-h-0` support for flex contexts +- Update flex child selectors to include min-height fixes +- Ensure backward compatibility with existing usage +- Test across different scroll scenarios + +#### Task 3.3: Test Scroll Fixes Across All Layouts + +**Files**: All layout components + +- Test Social Media layout with long content +- Test Video layout with long descriptions +- Test Articles layout for regressions +- Test Pictures layout after restructuring +- Verify mobile responsive behavior + +### Phase 4: Integration Testing and Polish (Priority: Medium) + +#### Task 4.1: Cross-Layout Consistency Testing + +- Verify typography consistency across all layouts +- Test avatar sizing consistency in different contexts +- Ensure PreviewMediaContent modal works consistently +- Test scroll behavior across all entry types + +#### Task 4.2: Performance and Accessibility Testing + +- Verify no performance regressions with scroll fixes +- Test keyboard navigation with new carousel behavior +- Ensure proper focus management in PreviewMediaContent +- Test screen reader compatibility + +## Context & References + +### Codebase Architecture Understanding + +#### Core Components to Modify + +- **AuthorHeader.tsx**: Typography improvements for author names +- **FeedIcon.tsx**: Size-responsive border radius implementation +- **PicturesLayout.tsx**: Single image display with carousel integration +- **ScrollArea.tsx**: Flex container height calculation fixes +- **EntryContent.tsx**: Scroll container height fixes +- **picture-item.tsx**: Restore image click preview behavior + +#### Existing Patterns to Follow + +- **PreviewMediaContent.tsx**: Modal-based media carousel (Embla carousel integration) +- **usePreviewMedia**: Hook for triggering media preview modals +- **Media component**: Image display with loading states and proxy support +- **UIKit color system**: Consistent with `text-base`, `rounded-lg` etc. + +### External Best Practices & Documentation + +#### CSS Flexbox Height Calculation Fixes + +- **Min-Height Zero Pattern**: https://stackoverflow.com/questions/21515042/scrolling-a-flexbox-with-overflowing-content +- **Flex Container Overflow**: https://moduscreate.com/blog/how-to-fix-overflow-issues-in-css-flex-layouts/ +- **Critical Insight**: "There's a special case where the min-height of flex items defaults to the content size. We have to explicitly set the min height to zero." + +#### React Image Carousel Best Practices + +- **Single Image Display**: https://cloudinary.com/blog/add-a-responsive-image-carousel-to-your-react-app +- **Click Navigation**: Custom controls with callback functions and hasNext/hasPrev state +- **Responsive Design**: Automatic layout adjustment based on screen size +- **Performance**: Lazy loading and video play control on selected slides + +#### Typography and Avatar Scaling + +- **Responsive Avatar Sizing**: Border radius should scale proportionally with avatar size +- **Social Media Typography**: Author names should be prominent (16px+ / text-base) for readability +- **Apple UIKit Standards**: Consistent size relationships (border radius = size/6 to size/4) + +### Implementation Guidelines + +#### Typography Scaling Pattern + +```typescript +// Size-based styling patterns +const getFontSize = (context: "social" | "article" | "compact") => { + switch (context) { + case "social": + return "text-base font-semibold" // 16px for prominence + case "article": + return "text-sm font-semibold" // 14px for articles + case "compact": + return "text-xs font-medium" // 12px for compact + } +} +``` + +#### Border Radius Scaling Pattern + +```typescript +// Size-responsive border radius +const getBorderRadius = (size: number) => { + const ratio = size / 8 // Scale factor + if (ratio <= 3) return "rounded-sm" // 2px + if (ratio <= 4) return "rounded-md" // 6px + if (ratio <= 6) return "rounded-lg" // 8px + return "rounded-xl" // 12px +} +``` + +#### Single Image Carousel Pattern + +```typescript +// Media display with carousel integration +const handleImageClick = useCallback(() => { + if (mediaArray.length > 0) { + previewMedia( + mediaArray.map(transformMediaForPreview), + 0, // Initial index + ) + } +}, [mediaArray, previewMedia]) +``` + +## Validation Gates + +### Code Quality Checks + +```bash +# TypeScript validation +pnpm run typecheck + +# Linting validation +pnpm run lint:tsl +pnpm run lint + +# Code formatting +pnpm run format + +# Build validation +pnpm run build:web +``` + +### Functional Testing Checklist + +#### Social Media Layout Validation + +- [ ] Author name displays with `text-base` font size (16px) +- [ ] Author name maintains proper font weight and color +- [ ] Avatar border radius scales appropriately with 48px size +- [ ] Avatar maintains circular appearance with proper radius +- [ ] Typography is consistent across different author name lengths +- [ ] Layout maintains proper spacing and alignment + +#### Pictures Layout Validation + +- [ ] Single image displays instead of multiple images side by side +- [ ] First image from media array is shown as primary display +- [ ] "+X more" indicator appears when multiple images exist +- [ ] Clicking single image opens PreviewMediaContent modal +- [ ] Carousel navigation works properly in modal (left/right arrows) +- [ ] Image maintains proper aspect ratio and scaling +- [ ] No layout shift when transitioning to/from modal + +#### Entry List Image Click Validation + +- [ ] Clicking images in picture-item triggers PreviewMediaContent modal +- [ ] Modal opens with correct initial image and media array +- [ ] Entry navigation still works when clicking non-image areas +- [ ] No conflicts between image click and entry click behaviors +- [ ] Touch gestures work properly on mobile devices + +#### Scroll Container Height Validation + +- [ ] Long content no longer gets cut off at bottom in Social Media layout +- [ ] Long content no longer gets cut off at bottom in Video layout +- [ ] ScrollArea height matches available container height +- [ ] Content scrolls smoothly to very bottom without truncation +- [ ] No visual glitches or layout shifts during scrolling +- [ ] Fix applies to all entry types (Articles, Social Media, Videos, Pictures) +- [ ] Mobile responsive behavior maintains proper scrolling + +### Performance & Integration Testing + +- [ ] No layout shift when switching between entry types +- [ ] PreviewMediaContent modal opens smoothly without lag +- [ ] Image loading states display properly +- [ ] Scroll performance maintained with height fixes +- [ ] No memory leaks with modal-based image preview +- [ ] Typography rendering remains crisp at all zoom levels + +## Success Criteria + +### Primary Objectives + +- [ ] **Social Media**: Author names display prominently with proper typography +- [ ] **Social Media**: Avatar border radius scales appropriately with size +- [ ] **Pictures**: Single image display with click-to-carousel functionality +- [ ] **Pictures**: Entry list image clicking restored and working properly +- [ ] **Scroll Heights**: Long content fully visible without truncation in all layouts +- [ ] **Performance**: All fixes implemented without performance regression + +### Quality Standards + +- [ ] Zero regressions in existing ArticleLayout functionality +- [ ] All layout types maintain consistent typography patterns +- [ ] PreviewMediaContent modal integration works seamlessly +- [ ] ScrollArea height calculation robust across different content types +- [ ] Mobile responsive design maintained across all fixes + +### User Experience Improvements + +- [ ] Social media author information more readable and prominent +- [ ] Picture viewing experience enhanced with proper carousel integration +- [ ] Content consumption improved with full scroll accessibility +- [ ] Visual consistency improved with proper avatar styling +- [ ] Interaction patterns consistent between entry list and content view + +## Risk Assessment & Mitigation + +### High-Risk Areas + +#### 1. ScrollArea Height Calculation Changes + +**Risk**: Height fixes might break existing scroll behavior in other components +**Mitigation**: + +- Apply changes incrementally with thorough testing +- Maintain backward compatibility with existing ScrollArea usage +- Test all scroll containers across the application +- Use feature flags for gradual rollout if needed + +#### 2. PreviewMediaContent Modal Integration + +**Risk**: Modal stacking conflicts or keyboard navigation issues +**Mitigation**: + +- Test modal behavior with existing modal stack system +- Verify proper cleanup of modal state +- Ensure keyboard navigation (ESC, arrows) works correctly +- Test touch gestures on mobile devices + +#### 3. Typography Changes Impact + +**Risk**: Font size changes might break layout in compact or mobile views +**Mitigation**: + +- Test with various author name lengths and special characters +- Verify responsive behavior across all screen sizes +- Check international character rendering (CJK, Arabic, etc.) +- Maintain proper line height and spacing + +### Medium-Risk Areas + +#### Component Dependencies + +**Risk**: Changes to shared components might affect other features +**Mitigation**: + +- Audit all usage of modified components before changes +- Use backward-compatible prop additions +- Test AuthorHeader and FeedIcon usage across application +- Verify no breaking changes to component APIs + +#### Image Loading Performance + +**Risk**: Single image display might affect loading performance +**Mitigation**: + +- Maintain existing lazy loading behavior +- Test image proxy functionality with new implementation +- Profile image loading performance before and after changes +- Ensure proper loading states and error handling + +### Rollback Strategy + +- Implement changes as separate commits for easy reversal +- Use CSS custom properties for easy typography adjustments +- Maintain original component implementations as backup +- Feature flag capability for critical scroll height fixes + +## Additional Considerations + +### Accessibility Standards + +- Ensure author names maintain proper contrast ratios with larger text +- Test screen reader compatibility with typography changes +- Verify keyboard navigation works properly with image carousel +- Maintain proper heading hierarchy across layout changes + +### Internationalization Support + +- Test typography changes with different language character sets +- Ensure proper text flow with RTL languages +- Verify avatar and text spacing works with longer translated text +- Maintain consistent translation key usage across components + +### Future Extensibility + +- Typography pattern scalable to other layout types +- Border radius pattern reusable for other avatar contexts +- ScrollArea fixes applicable to other scroll containers +- Image carousel pattern extensible to video content + +## Confidence Score: 9/10 + +This PRP provides a comprehensive solution with high implementation confidence: + +### Strengths + +- ✅ **Root Cause Analysis**: Identified exact source of each issue with specific file/line references +- ✅ **Proven External Research**: Incorporates CSS flexbox best practices and React carousel patterns +- ✅ **Focused Scope**: Addresses specific reported issues without unnecessary complexity +- ✅ **Detailed Implementation**: Clear component-by-component changes with code examples +- ✅ **Risk Management**: Identified potential issues with concrete mitigation strategies +- ✅ **Comprehensive Testing**: Detailed validation steps for each change +- ✅ **Existing Pattern Leverage**: Uses established components (PreviewMediaContent, usePreviewMedia) + +### Implementation Confidence Factors + +1. **Clear Problem Definition**: Each issue traced to specific code locations with examples +2. **External Best Practices**: CSS flexbox fixes and React carousel patterns are well-established +3. **Component Reuse**: Leveraging existing PreviewMediaContent rather than building new carousel +4. **Incremental Approach**: Changes can be implemented and tested independently +5. **Minimal Breaking Changes**: Most fixes involve styling adjustments and proper component usage +6. **Established Patterns**: Typography and avatar sizing follow existing codebase conventions + +### Minor Risk Areas + +- **ScrollArea Changes**: Need thorough testing across different content types +- **Typography Impact**: Must verify responsive behavior with larger text +- **Modal Integration**: Ensure smooth interaction with existing modal stack + +The high confidence score reflects that this PRP addresses well-defined styling and functional issues using established patterns and external best practices, with clear implementation steps and comprehensive validation approaches. diff --git a/PRPs/entry-modal-to-routing.md b/PRPs/entry-modal-to-routing.md new file mode 100644 index 000000000..ea9528628 --- /dev/null +++ b/PRPs/entry-modal-to-routing.md @@ -0,0 +1,278 @@ +# PRP: Entry Modal to Routing Refactoring + +## Overview + +Refactor the entry content display system from a full-page modal approach to a scoped, column-based routing approach. This will improve user experience by keeping the modal scoped to the entry list column and make the entry content display reflect in the URL for better navigation. + +## Current Implementation Analysis + +### Current Architecture + +- **Three-column layout**: Feed list (left) → Entry list (center) → AI chat (right) +- **Main layout**: `MainDestopLayout` → `SubscriptionColumnContainer` + `` (`CenterColumnLayout`) +- **Entry list**: Located in `CenterColumnLayout` which contains `EntryColumn` and `AIChatLayout` +- **Modal system**: Uses `usePeekModal` hook to display entry content in a full-page modal + +### Key Files & Components + +#### Current Modal Implementation + +- **`usePeekModal.tsx`**: Hook that creates full-page modal using `PeekModal` component +- **`EntryItemWrapper.tsx:126`**: Click handler calls `peekModal(entry.id, "modal")` instead of navigation +- **`PeekModal` component**: Renders modal with `modalClassName` covering entire viewport + +#### Routing Infrastructure + +- **`useNavigateEntry.ts`**: Contains `getNavigateEntryPath()` function that generates proper entry URLs +- **Route structure**: `/timeline/:timelineId/:feedId/:entryId` +- **Current entry routing**: + - Layout: `/timeline/[timelineId]/[feedId]/layout.tsx` → `CenterColumnLayout` + - Index: `/timeline/[timelineId]/[feedId]/index.tsx` → redirects to `ROUTE_ENTRY_PENDING` + - Entry: `/timeline/[timelineId]/[feedId]/[entryId]/index.tsx` → `EntryLayoutContent` + +#### Layout Components + +- **`CenterColumnLayout.tsx`**: Two-column layout with entry list and AI chat +- **`EntryLayoutContent.tsx`**: Renders entry content when entryId is present in URL +- **`MainDestopLayout.tsx`**: Root layout with feed column and main content outlet + +### Current Flow + +1. User clicks entry in `EntryItemWrapper` +2. `handleClick` calls `peekModal(entry.id, "modal")` +3. Modal covers entire viewport, disrupting three-column layout +4. Entry content not reflected in URL routing + +## Proposed Solution + +### Architecture Changes + +Transform the entry content display from a modal overlay to a proper routing-based approach that renders within the entry column scope. + +### New Flow + +1. User clicks entry in `EntryItemWrapper` +2. `handleClick` calls `navigateEntry()` with `getNavigateEntryPath()` +3. URL changes to `/timeline/:timelineId/:feedId/:entryId` +4. Entry content renders within entry column boundaries via `` + +### Key Modifications + +#### 1. Modify Entry Click Handler + +**File**: `apps/desktop/layer/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx:115-129` + +Replace modal invocation with navigation: + +```typescript +// BEFORE +const handleClick = useCallback( + (e) => { + // ... existing logic + peekModal(entry.id, "modal") + }, + [peekModal], +) + +// AFTER +const handleClick = useCallback( + (e) => { + // ... existing logic + navigateEntry({ entryId: entry.id }) + }, + [navigateEntry], +) +``` + +#### 2. Update CenterColumnLayout for Entry Display + +**File**: `apps/desktop/layer/renderer/src/modules/app-layout/timeline-column/CenterColumnLayout.tsx` + +Add conditional rendering for entry content within the entry column: + +```typescript +// Current: Simple two-column layout +
+ +
+ +// Proposed: Conditional entry content display +
+ + {/* Renders entry content when entryId is present */} +
+``` + +#### 3. Create Column-Scoped Entry Layout + +**New file**: `apps/desktop/layer/renderer/src/modules/entry-column/EntryColumnLayout.tsx` + +```typescript +export const EntryColumnLayout = () => { + const { entryId } = useParams() + const navigate = useNavigateEntry() + + if (!entryId || entryId === ROUTE_ENTRY_PENDING) { + return + } + + return ( +
+ {/* Entry list background */} + + + {/* Entry content overlay within column */} +
+ navigate({ entryId: null })} + /> +
+
+ ) +} +``` + +#### 4. Update Route Configuration + +**File**: `apps/desktop/layer/renderer/src/pages/(main)/(layer)/timeline/[timelineId]/[feedId]/layout.tsx` + +Change from `CenterColumnLayout` to new scoped layout: + +```typescript +// BEFORE +export { CenterColumnLayout as Component } from "~/modules/app-layout/timeline-column/index" + +// AFTER +export { EntryColumnLayout as Component } from "~/modules/entry-column/EntryColumnLayout" +``` + +## Implementation Tasks + +### Phase 1: Core Routing Setup + +1. **Create EntryColumnLayout component** + - Implement conditional rendering for entry content + - Add proper scoping within entry column boundaries + - Handle entry close navigation + +2. **Update CenterColumnLayout route** + - Replace component export in layout.tsx + - Ensure proper outlet rendering + +3. **Modify EntryItemWrapper click handler** + - Replace `peekModal` call with `navigateEntry` + - Import and use existing navigation utilities + +### Phase 2: Layout & Styling + +4. **Style scoped entry content** + - Ensure entry content stays within column boundaries + - Add proper animations for entry open/close + - Handle responsive behavior + +5. **Update entry content close behavior** + - Remove modal-specific close logic + - Implement navigation-based close + +### Phase 3: Testing & Validation + +6. **Test navigation flow** + - Verify URL changes correctly + - Test browser back/forward navigation + - Validate entry content display + +7. **Test edge cases** + - Direct URL access to entry routes + - Entry not found scenarios + - Mobile responsiveness + +## Context & References + +### Existing Patterns + +- **Navigation utilities**: `useNavigateEntry`, `getNavigateEntryPath` already exist +- **Route structure**: Entry routing infrastructure already present +- **Entry content component**: `EntryContent` component already handles rendering + +### External Documentation + +- **React Router Modal Patterns**: https://blog.logrocket.com/building-react-modal-module-with-react-router/ +- **Background Location Pattern**: https://dev.to/unorthodev/how-to-make-routable-modals-in-react-with-react-router-3hgp +- **Scoped Navigation**: https://github.com/remix-run/react-router/discussions/9601 + +### Best Practices Applied + +1. **Nested Route Approach**: Use existing route structure with outlets +2. **Scoped Rendering**: Keep entry content within column boundaries +3. **Persistent Navigation**: URL reflects entry selection state +4. **Smooth Transitions**: Maintain existing animation patterns + +## Validation Gates + +### Code Quality + +```bash +# TypeScript validation +pnpm run typecheck + +# Linting +pnpm run lint + +# Build validation +pnpm run build:web +``` + +### Functional Testing + +```bash +# Manual testing checklist +1. Click entry in list → URL updates → Entry content displays in column +2. Browser back/forward → Entry content appears/disappears correctly +3. Direct URL access → Entry content renders properly +4. Entry close action → Returns to entry list with correct URL +5. Mobile responsiveness → Entry content adapts to smaller screens +``` + +### Performance Validation + +- No increase in bundle size +- Smooth animations maintained +- No layout shifts during entry display + +## Success Criteria + +- [ ] Entry clicks trigger navigation instead of modal +- [ ] Entry content displays within column boundaries +- [ ] URL reflects entry selection state +- [ ] Browser navigation works correctly +- [ ] Entry close returns to proper state +- [ ] All existing functionality preserved +- [ ] No visual regression in three-column layout + +## Risk Mitigation + +### Potential Issues + +1. **Layout disruption**: Entry content might overflow column boundaries +2. **Animation conflicts**: Existing animations might conflict with new approach +3. **Mobile compatibility**: Column-scoped display might not work on mobile + +### Mitigation Strategies + +1. **Absolute positioning**: Use absolute positioning to contain entry content +2. **CSS containment**: Use CSS containment properties for layout isolation +3. **Responsive design**: Implement mobile-specific fallbacks if needed + +## Confidence Score: 8/10 + +This PRP provides a comprehensive approach with: + +- ✅ Detailed analysis of current implementation +- ✅ Clear technical specifications +- ✅ Existing code patterns leveraged +- ✅ External best practices incorporated +- ✅ Executable validation steps +- ✅ Risk mitigation strategies + +The high confidence comes from the existing navigation infrastructure and clear understanding of the current modal system. The main implementation involves connecting existing pieces rather than building from scratch.