Implements complete post management and social interaction capabilities: **Post Management:** - Delete posts with confirmation dialog (owned posts only) - Edit posts using existing compose dialog (owned posts only) - Robust ownership validation and error handling **Follow System:** - Follow/unfollow users from context menus and keyboard shortcuts - Manual follow dialog for @user@instance lookups - Account search and validation before following - Smart context menu options based on post ownership **Timeline Extensions:** - Followers tab showing accounts following you - Following tab showing accounts you follow - Seamless integration with existing timeline system - Account list display for social relationship viewing **Keyboard Shortcuts:** - Ctrl+Shift+E: Edit post - Shift+Delete: Delete post (with confirmation) - Ctrl+Shift+F: Follow user - Ctrl+Shift+U: Unfollow user - Ctrl+Shift+M: Manual follow dialog **ActivityPub API Extensions:** - edit_status() method for post editing - get_relationship() method for follow status checking - Enhanced followers/following pagination support **Critical Accessibility Fix:** - Eliminated ALL text truncation throughout the application - Added explicit no-truncation rule to development guidelines - Full content accessibility for screen reader users All features maintain Bifrost's accessibility-first principles with proper error handling, user feedback, and complete information display. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
13 KiB
Bifrost Fediverse Client - Development Plan
Project Overview
Bifrost is a fully accessible fediverse client built with PySide6, designed specifically for screen reader users. The application uses "post/posts" terminology instead of "toot" and focuses on excellent keyboard navigation and audio feedback.
Core Features
- Full ActivityPub protocol support (Pleroma and GoToSocial primary targets)
- Threaded conversation navigation with collapsible tree view
- Comprehensive soundpack management system with secure repository support
- Smart autocomplete for mentions (@user@instance.com) and emojis (5,000+ Unicode)
- Auto-refresh with intelligent activity-based timing
- Screen reader optimized interface with Orca compatibility fixes
- XDG Base Directory specification compliance
Technology Stack
- PySide6: Main GUI framework (proven accessibility with existing doom launcher)
- requests: HTTP client for ActivityPub APIs
- simpleaudio: Cross-platform audio with subprocess fallback
- emoji: Comprehensive Unicode emoji library (5,000+ emojis with keyword search)
- plyer: Cross-platform desktop notifications
- XDG directories: Configuration and data storage
Architecture
Directory Structure
bifrost/
├── bifrost/
│ ├── __init__.py
│ ├── main.py # Application entry point
│ ├── accessibility/ # Accessibility widgets and helpers
│ │ ├── __init__.py
│ │ ├── accessible_tree.py # AccessibleTreeWidget for conversations
│ │ └── accessible_combo.py # Enhanced ComboBox from doom launcher
│ ├── activitypub/ # Federation protocol handling
│ │ ├── __init__.py
│ │ ├── client.py # Main ActivityPub client
│ │ ├── pleroma.py # Pleroma-specific implementation
│ │ └── gotosocial.py # GoToSocial-specific implementation
│ ├── models/ # Data models
│ │ ├── __init__.py
│ │ ├── post.py # Post data structure
│ │ ├── user.py # User profiles
│ │ ├── timeline.py # Timeline model for QTreeView
│ │ └── thread.py # Conversation threading
│ ├── widgets/ # Custom UI components
│ │ ├── __init__.py
│ │ ├── timeline_view.py # Main timeline widget with auto-refresh
│ │ ├── compose_dialog.py # Post composition with smart autocomplete
│ │ ├── autocomplete_textedit.py # Mention and emoji autocomplete system
│ │ ├── settings_dialog.py # Application settings
│ │ ├── soundpack_manager_dialog.py # Soundpack repository management
│ │ └── login_dialog.py # Instance login
│ ├── audio/ # Sound system
│ │ ├── __init__.py
│ │ ├── sound_manager.py # Audio notification handler
│ │ └── soundpack_manager.py # Secure soundpack installation system
│ │ └── sound_pack.py # Sound pack management
│ └── config/ # Configuration management
│ ├── __init__.py
│ ├── settings.py # Settings handler with XDG compliance
│ └── accounts.py # Account management
├── sounds/ # Sound packs directory
│ ├── default/
│ │ ├── pack.json
│ │ ├── private_message.wav
│ │ ├── mention.wav
│ │ ├── boost.wav
│ │ ├── reply.wav
│ │ ├── post_sent.wav
│ │ ├── timeline_update.wav
│ │ └── notification.wav
│ └── doom/ # Example themed sound pack
│ ├── pack.json
│ └── *.wav files
├── tests/
│ ├── __init__.py
│ ├── test_accessibility.py
│ ├── test_activitypub.py
│ └── test_audio.py
├── requirements.txt
├── setup.py
└── README.md
XDG Directory Usage
- Config:
~/.config/bifrost/
- Settings, accounts, current sound pack - Data:
~/.local/share/bifrost/
- Sound packs, cached data - Cache:
~/.cache/bifrost/
- Temporary files, avatar cache
Accessibility Implementation
From Doom Launcher Success
- AccessibleComboBox: Enhanced keyboard navigation (Page Up/Down, Home/End)
- Proper Accessible Names: All widgets get descriptive
setAccessibleName()
- Focus Management: Clear tab order and focus indicators
- No Custom Speech: Screen reader handles all announcements
Threaded Conversation Navigation
Navigation Pattern:
Timeline Item: "Alice posted: Hello world (3 replies, collapsed)"
[Right Arrow] → "Alice posted: Hello world (3 replies, expanded)"
[Down Arrow] → " Bob replied: Hi there"
[Down Arrow] → " Carol replied: How's it going?"
[Down Arrow] → "David posted: Another topic"
Key Behaviors:
- Right Arrow: Expand thread, announce "expanded"
- Left Arrow: Collapse thread, announce "collapsed"
- Down Arrow: Next item (skip collapsed children)
- Up Arrow: Previous item
- Page Down/Up: Jump 5 items
- Home/End: First/last item
AccessibleTreeWidget Requirements
- Inherit from QTreeWidget
- Override keyPressEvent for custom navigation
- Proper accessibility roles and states
- Focus management for nested items
- Status announcements via Qt accessibility
Sound System Design
Sound Events
- startup: Application started
- shutdown: Application closing
- private_message: Direct message received
- mention: User mentioned in post
- boost: Post boosted/reblogged
- reply: Reply to user's post
- post_sent: User successfully posted
- timeline_update: New posts in timeline
- notification: General notification
- expand: Thread expanded
- collapse: Thread collapsed
- success: General success feedback
- error: Error occurred
Sound Pack Structure
pack.json Format:
{
"name": "Pack Display Name",
"description": "Pack description",
"author": "Creator name",
"version": "1.0",
"sounds": {
"private_message": "filename.wav",
"mention": "filename.wav",
"boost": "filename.wav",
"reply": "filename.wav",
"post_sent": "filename.wav",
"timeline_update": "filename.wav",
"notification": "filename.wav"
}
}
SoundManager Features
- simpleaudio for cross-platform WAV playback with volume control
- Subprocess fallback (sox/play on Linux, afplay on macOS, PowerShell on Windows)
- Fallback to default pack if sound missing
- Master volume and notification volume controls
- Enable/disable per event
- Pack discovery and validation
- Smart threading (direct calls for simpleaudio, threaded for subprocess)
ActivityPub Implementation
Core Client Features
- Timeline Streaming: Real-time updates via WebSocket/polling
- Post Composition: Text, media attachments, visibility settings
- Thread Resolution: Fetch complete conversation trees
- User Profiles: Following, followers, profile viewing
- Notifications: Mentions, boosts, follows, favorites
Server Compatibility
Primary Targets:
- Pleroma: Full feature support
- GoToSocial: Full feature support
Extended Support:
- Mastodon: Best effort compatibility
- Other ActivityPub servers: Basic functionality
API Endpoints Usage
/api/v1/timelines/home
- Home timeline/api/v1/statuses
- Post creation/api/v1/statuses/:id/context
- Thread fetching/api/v1/streaming
- Real-time updates/api/v1/notifications
- Notification management
User Interface Design
Main Window Layout
[Menu Bar]
[Instance/Account Selector]
[Timeline Tree View - Main Focus]
[Compose Box]
[Status Bar]
Key UI Components
- Timeline View: AccessibleTreeWidget showing posts and threads with pagination
- Timeline Tabs: Home, Mentions, Local, Federated timeline switching
- Compose Dialog: Modal for creating posts with accessibility
- Settings Dialog: Sound pack, desktop notifications, accessibility options
- Login Dialog: Instance selection and authentication
- URL Selection Dialog: Choose from multiple URLs in posts
- Context Menu: Copy, URL opening, reply, boost, favorite actions
Keyboard Shortcuts
- Ctrl+N: New post
- Ctrl+R: Reply to selected post
- Ctrl+B: Boost selected post
- Ctrl+F: Favorite selected post
- Ctrl+C: Copy selected post to clipboard
- Ctrl+U: Open URLs from selected post in browser
- F5: Refresh timeline
- Ctrl+,: Settings
- Escape: Close dialogs
Development Phases
Phase 1: Foundation
- Project structure setup
- XDG configuration system
- Basic PySide6 window with accessibility
- AccessibleTreeWidget implementation
- Sound system foundation
Phase 2: ActivityPub Core
- Basic HTTP client
- Authentication (OAuth2)
- Timeline fetching and display
- Post composition and sending
- Basic thread display
Phase 3: Advanced Features
- Thread expansion/collapse
- Real-time updates
- Notifications system
- Sound pack system
- Settings interface
Phase 4: Polish
- Comprehensive accessibility testing
- Screen reader testing (Orca, NVDA, JAWS)
- Performance optimization
- Error handling
- Documentation
Testing Strategy
Accessibility Testing
- Automated testing with screen reader APIs
- Manual testing with Orca, NVDA (via Wine)
- Keyboard-only navigation testing
- Focus management verification
Functional Testing
- ActivityPub protocol compliance
- Thread navigation accuracy
- Sound system reliability
- Configuration persistence
Test Instances
- Pleroma test server
- GoToSocial test server
- Mock ActivityPub server for edge cases
Configuration Management
Settings Structure
[general]
instance_url = https://example.social
username = user
timeline_refresh_interval = 60
[audio]
sound_pack = Doom
master_volume = 100
notification_volume = 100
[sounds]
private_message_enabled = true
private_message_volume = 0.8
mention_enabled = true
mention_volume = 1.0
# ... other sound settings
[notifications]
enabled = true
direct_messages = true
mentions = true
boosts = false
favorites = false
follows = true
timeline_updates = false
[timeline]
posts_per_page = 40
[accessibility]
announce_thread_state = true
auto_expand_mentions = false
keyboard_navigation_wrap = true
page_step_size = 5
verbose_announcements = true
Account Storage
- Secure credential storage
- Multiple account support
- Instance-specific settings
Known Challenges and Solutions
ActivityPub Complexity
- Challenge: Different server implementations vary
- Solution: Modular client design with server-specific adapters
Screen Reader Performance
- Challenge: Large timelines may impact performance
- Solution: Virtual scrolling, lazy loading, efficient tree models
Thread Visualization
- Challenge: Complex thread structures hard to navigate
- Solution: Clear indentation, status announcements, skip collapsed
Sound Customization
- Challenge: Users want different audio feedback
- Solution: Comprehensive sound pack system with easy installation
Future Enhancements
Advanced Features
- Custom timeline filters
- Multiple column support
- Direct message interface
- List management
- Advanced search
Accessibility Extensions
- Braille display optimization
- Voice control integration
- High contrast themes
- Font size scaling
Federation Features
- Cross-instance thread following
- Server switching
- Federation status monitoring
- Custom emoji support
Dependencies
Core Requirements
PySide6>=6.0.0
requests>=2.25.0
simpleaudio>=1.0.4
plyer>=2.1.0
emoji>=2.0.0
Optional Dependencies
pytest (testing)
coverage (test coverage)
black (code formatting)
mypy (type checking)
Installation and Distribution
Development Setup
git clone <repository>
cd bifrost
pip install -r requirements.txt
# Run with proper display
DISPLAY=:0 ./bifrost.py
# Or
python bifrost.py
Packaging
- Python wheel distribution
- AppImage for Linux
- Consideration for distro packages
Accessibility Compliance
Standards Adherence
- WCAG 2.1 AA compliance
- Qt Accessibility framework usage
- AT-SPI2 protocol support (Linux)
- Platform accessibility APIs
Screen Reader Testing Matrix
- Orca (Linux): Primary target
- NVDA (Windows via Wine): Secondary
- JAWS (Windows via Wine): Basic compatibility
- VoiceOver (macOS): Future consideration
Critical Accessibility Rules
Text Truncation Is Forbidden
NEVER TRUNCATE TEXT: Bifrost is an accessibility-first client. Text truncation (using "..." or limiting character counts) is strictly forbidden as it prevents screen reader users from accessing complete information. Always display full content, descriptions, usernames, profiles, and any other text in its entirety.
Examples of forbidden practices:
content[:100] + "..."
- Character limits on display text
- Shortened usernames or descriptions
- Abbreviated profile information
This document serves as the comprehensive development guide for Bifrost, ensuring all accessibility, functionality, and architectural decisions are preserved and can be referenced throughout development.