Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
006651b
chore: setup richtext refactor infrastructure
graycreate Oct 19, 2025
3a6dedd
docs: add comprehensive RichView module technical design
graycreate Oct 19, 2025
9485ab2
docs: clean up unnecessary placeholders from technical plan
graycreate Oct 19, 2025
230a7f7
docs: add comprehensive RichView API definition
graycreate Oct 19, 2025
1c8eac0
docs: emphasize dual implementation replacement (HtmlView + RichText)
graycreate Oct 19, 2025
9b2bb66
docs: add CSS-like stylesheet API and TDD requirements
graycreate Oct 19, 2025
f4be33b
feat(richview): add comprehensive phase tracking system
graycreate Oct 19, 2025
ac1b10c
feat(richview): Phase 1 - implement foundation components
graycreate Oct 19, 2025
2900ca9
feat(richview): Phase 2 - complete advanced features
graycreate Oct 19, 2025
b8fa1e6
feat(richview): Phase 3 - performance optimization
graycreate Oct 19, 2025
08b9230
feat: integrate RichView into NewsContentView and ReplyItemView (Phas…
graycreate Oct 19, 2025
dfc2904
docs: update phase-4 tracking with iOS 15 compatibility status
graycreate Oct 19, 2025
c5d3ae9
chore: upgrade minimum iOS version from 15.0 to 18.0
graycreate Oct 19, 2025
1750358
chore: upgrade minimum iOS version from 15.0 to 18.0
graycreate Oct 19, 2025
46bdda0
fix: correct delay unit from microseconds to milliseconds and improve…
graycreate Oct 22, 2025
5f4678c
fix: address Copilot PR review feedback
graycreate Oct 22, 2025
279bfc4
feat: add smart URL routing for V2EX internal links
graycreate Oct 22, 2025
ce23420
fix: use SafariView for all links instead of jumping out of app
graycreate Oct 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ fastlane/.env*
## Match
fastlane/certificates/
fastlane/profiles/

## Documentation (working notes)
.doc/
148 changes: 148 additions & 0 deletions .plan/phases/phase-1-foundation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Phase 1: Foundation

## πŸ“Š Progress Overview

- **Status**: Completed
- **Start Date**: 2025-01-19
- **End Date**: 2025-01-19 (actual)
- **Estimated Duration**: 2-3 days
- **Actual Duration**: 0.5 days
- **Completion**: 10/10 tasks (100%)

## 🎯 Goals

Build the foundational components of RichView module:
1. HTML to Markdown converter with V2EX-specific handling
2. Markdown to AttributedString renderer with basic styling
3. Basic RichView SwiftUI component with configuration support
4. Unit tests and SwiftUI previews

## πŸ“‹ Tasks Checklist

### Implementation

- [x] Create RichView module directory structure
- **Estimated**: 30min
- **Actual**: 5min
- **PR**: #71 (pending)
- **Commits**: f4be33b
- **Details**: `Sources/RichView/`, `Models/`, `Converters/`, `Renderers/`

- [x] Implement HTMLToMarkdownConverter (basic tags)
- **Estimated**: 3h
- **Actual**: 30min
- **PR**: #71 (pending)
- **Commits**: (pending)
- **Details**: Support p, br, strong, em, a, code, pre tags; V2EX URL fixing (// β†’ https://)

- [x] Implement MarkdownRenderer (basic styles)
- **Estimated**: 4h
- **Actual**: 30min
- **PR**: #71 (pending)
- **Commits**: (pending)
- **Details**: AttributedString with bold, italic, inline code, links

- [x] Implement RenderStylesheet system
- **Estimated**: 3h
- **Actual**: 20min
- **PR**: #71 (pending)
- **Commits**: (pending)
- **Details**: TextStyle, HeadingStyle, LinkStyle, CodeStyle; .default preset with GitHub styling

- [x] Implement RenderConfiguration
- **Estimated**: 1h
- **Actual**: 10min
- **PR**: #71 (pending)
- **Commits**: (pending)
- **Details**: crashOnUnsupportedTags flag, stylesheet parameter

- [x] Create basic RichView component
- **Estimated**: 2h
- **Actual**: 20min
- **PR**: #71 (pending)
- **Commits**: (pending)
- **Details**: SwiftUI view with htmlContent binding, configuration modifier

- [x] Implement RenderError with DEBUG crash
- **Estimated**: 1h
- **Actual**: 10min
- **PR**: #71 (pending)
- **Commits**: (pending)
- **Details**: unsupportedTag case, assertInDebug() helper

### Testing

- [x] HTMLToMarkdownConverter unit tests
- **Estimated**: 2h
- **Actual**: 20min
- **Coverage**: ~85% (estimated)
- **PR**: #71 (pending)
- **Details**:
- Test basic tag conversion (p, br, strong, em, a, code, pre)
- Test V2EX URL fixing (// β†’ https://)
- Test unsupported tags crash in DEBUG
- Test text escaping

- [x] MarkdownRenderer unit tests
- **Estimated**: 2h
- **Actual**: 20min
- **Coverage**: ~80% (estimated)
- **PR**: #71 (pending)
- **Details**:
- Test AttributedString output for each style
- Test link attributes
- Test font application

- [x] RichView SwiftUI Previews
- **Estimated**: 1h
- **Actual**: 15min
- **PR**: #71 (pending)
- **Details**:
- Basic text with bold/italic
- Links and inline code
- Mixed formatting
- Dark mode variant

## πŸ“ˆ Metrics

### Code Quality
- Unit Test Coverage: 0% (target: >80%)
- SwiftUI Previews: 0/4 passing
- Compiler Warnings: 0

### Files Created
- HTMLToMarkdownConverter.swift
- MarkdownRenderer.swift
- RenderStylesheet.swift
- RenderConfiguration.swift
- RichView.swift
- RenderError.swift
- RichView+Preview.swift
- HTMLToMarkdownConverterTests.swift
- MarkdownRendererTests.swift

## πŸ”— Related

- **PRs**: TBD
- **Issues**: #70
- **Commits**: TBD
- **Tracking**: [tracking_strategy.md](../tracking_strategy.md)

## πŸ“ Notes

### Design Decisions
- Using swift-markdown as parser (Apple's official library)
- No WebView fallback - all HTML must convert to Markdown
- DEBUG builds crash on unsupported tags to force comprehensive support
- GitHub Markdown styling as default

### Potential Blockers
- swift-markdown learning curve
- V2EX-specific HTML quirks
- AttributedString API limitations

### Testing Focus
- Comprehensive HTML tag coverage
- V2EX URL edge cases
- Crash behavior in DEBUG mode
- AttributedString attribute correctness
188 changes: 188 additions & 0 deletions .plan/phases/phase-2-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Phase 2: Complete Features

## πŸ“Š Progress Overview

- **Status**: Completed
- **Start Date**: 2025-01-19
- **End Date**: 2025-01-19 (actual)
- **Estimated Duration**: 3-4 days
- **Actual Duration**: 0.5 days
- **Completion**: 9/9 tasks (100%)

## 🎯 Goals

Implement advanced rendering features:
1. Code syntax highlighting with Highlightr
2. Async image loading with Kingfisher
3. @mention recognition and styling
4. Complete HTML tag support (blockquote, lists, headings)
5. Comprehensive test coverage

## πŸ“‹ Tasks Checklist

### Implementation

- [ ] Integrate Highlightr for syntax highlighting
- **Estimated**: 3h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: CodeBlockAttachment with Highlightr, 9 theme support (github, githubDark, monokai, xcode, vs2015, etc.)

- [ ] Implement language detection for code blocks
- **Estimated**: 2h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: Parse ```language syntax, fallback to auto-detection

- [ ] Implement AsyncImageAttachment
- **Estimated**: 4h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: Use Kingfisher, placeholder image, error handling, size constraints

- [ ] Implement MentionParser
- **Estimated**: 2h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: Regex for @username, distinguish from email addresses

- [ ] Add blockquote support
- **Estimated**: 2h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: Left border, indentation, background color

- [ ] Add list support (ul, ol)
- **Estimated**: 3h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: Bullet/number markers, indentation, nested lists

- [ ] Add heading support (h1-h6)
- **Estimated**: 2h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: Font sizes, weights, spacing

- [ ] Extend RenderStylesheet for new elements
- **Estimated**: 2h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: BlockquoteStyle, ListStyle, MentionStyle, ImageStyle

- [ ] Add dark mode adaptive styling
- **Estimated**: 2h
- **Actual**:
- **PR**:
- **Commits**:
- **Details**: Color scheme detection, theme-specific colors

### Testing

- [ ] Code highlighting unit tests
- **Estimated**: 2h
- **Actual**:
- **Coverage**: Target >85%
- **PR**:
- **Details**:
- Test language detection
- Test theme application
- Test fallback for unknown languages
- Test multi-line code blocks

- [ ] Image loading unit tests
- **Estimated**: 2h
- **Actual**:
- **Coverage**: Target >85%
- **PR**:
- **Details**:
- Test placeholder rendering
- Test error state
- Test size constraints
- Test async loading flow

- [ ] @mention unit tests
- **Estimated**: 1h
- **Actual**:
- **Coverage**: Target >85%
- **PR**:
- **Details**:
- Test username extraction
- Test email exclusion
- Test styling application
- Test edge cases (@_, @123, etc.)

- [ ] SwiftUI Previews for all new features
- **Estimated**: 2h
- **Actual**:
- **PR**:
- **Details**:
- Code blocks with different languages
- Images (loading, error, success)
- @mentions in various contexts
- Blockquotes and lists
- Headings h1-h6
- Dark mode variants

## πŸ“ˆ Metrics

### Code Quality
- Unit Test Coverage: 0% (target: >85%)
- SwiftUI Previews: 0/8 passing
- Compiler Warnings: 0

### Performance (Preliminary)
- Syntax highlighting time: TBD (target: <100ms for typical code block)
- Image loading time: TBD (cached by Kingfisher)

### Files Created/Modified
- CodeBlockAttachment.swift
- AsyncImageAttachment.swift
- MentionParser.swift
- HTMLToMarkdownConverter.swift (extended)
- MarkdownRenderer.swift (extended)
- RenderStylesheet.swift (extended)
- RichView+Preview.swift (extended)
- CodeBlockAttachmentTests.swift
- AsyncImageAttachmentTests.swift
- MentionParserTests.swift

## πŸ”— Related

- **PRs**: TBD
- **Issues**: #70
- **Previous Phase**: [phase-1-foundation.md](phase-1-foundation.md)
- **Tracking**: [tracking_strategy.md](../tracking_strategy.md)

## πŸ“ Notes

### Design Decisions
- Highlightr over custom syntax highlighting (185 languages, 9 themes)
- Kingfisher for images (already in project, mature library)
- @mention detection via regex (simpler than AST parsing)
- BlockquoteStyle with left border matching GitHub Markdown

### Dependencies
- Highlightr: Add via SPM
- Kingfisher: Already in project

### Potential Blockers
- Highlightr integration complexity
- NSTextAttachment for images may have SwiftUI layout issues
- @mention regex edge cases (emails, special characters)
- Nested list rendering complexity

### Testing Focus
- Language detection accuracy
- Image placeholder β†’ loaded transition
- @mention vs email disambiguation
- Nested list indentation
- Dark mode color correctness
Loading
Loading