- Fix unicode/apostrophe display in posts using proper HTML entity decoding - Add persistent timeline filter settings across application restarts - Fix reblog filter bypass in load-more and streaming post updates - Enhance soundpack installation validation and XDG directory handling - Update documentation with recent improvements and fixes All timeline filter preferences now persist between sessions, and the reblog filter properly works regardless of how posts are loaded into the timeline. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Bifrost
A fully accessible fediverse client built with PySide6, designed specifically for screen reader users.
Vibe Coding Project
This project was created through "vibe coding" - a collaborative development approach where a human (Storm Dragon) provides direction, requirements, and testing while an AI assistant (Claude) handles the actual code implementation. Vibe coding combines human creativity and domain expertise with AI's rapid development capabilities, resulting in functional software that meets real accessibility needs.
All code in this project was written by Claude (Anthropic's AI assistant) based on specifications and feedback from Storm Dragon.
Features
- Full ActivityPub Support: Compatible with Pleroma, GoToSocial, and other fediverse servers
- Screen Reader Optimized: Designed from the ground up for excellent accessibility
- Threaded Conversations: Navigate complex conversation trees with keyboard shortcuts
- Timeline Switching: Easy navigation between Home, Messages, Mentions, Local, Federated, Bookmarks, Followers, and Following timelines
- Smart Notifications: Intelligent sound system that distinguishes your own content from external mentions, DMs, and updates
- Customizable Audio Feedback: Rich sound pack system with themed audio notifications
- Soundpack Manager: Secure repository-based soundpack discovery and installation
- Smart Autocomplete: Mention completion with full fediverse handles (@user@instance.com)
- Comprehensive Emoji Support: 5,000+ Unicode emojis with keyword search
- Auto-refresh: Intelligent timeline updates with smart notification system
- Clean Interface: Focused on functionality over visual design
- Keyboard Navigation: Complete keyboard control with intuitive shortcuts
- Direct Message Interface: Dedicated conversation view with threading support
- Bookmarks: Save and view bookmarked posts in a dedicated timeline
- Poll Support: Create, vote in, and view results of fediverse polls with full accessibility
- User Profile Viewer: Comprehensive profile viewing with bio, fields, recent posts, and social actions
- Social Features: Follow/unfollow, block/unblock, and mute/unmute users directly from profiles
- Media Uploads: Attach images, videos, and audio files with accessibility-compliant alt text
- Post Details: Press Enter on any post to see detailed interaction information with poll integration
- Thread Expansion: Full conversation context fetching for complete thread viewing
- Blocked/Muted Management: Dedicated tabs for managing blocked and muted users
- Custom Emoji Support: Instance-specific emoji support with caching
- Post Editing: Edit your own posts and direct messages with full content preservation
- Profile Editing: Edit your profile information including display name, bio, profile fields, and privacy settings
- Search Functionality: Search for users, hashtags, and posts across the fediverse with dedicated search interface
- Timeline Filtering: Customize your timeline view by hiding/showing replies, boosts, mentions, and media content
- List Management: Create and manage custom lists with full CRUD operations and member management
- List Timelines: View focused timelines from your created lists with dedicated list timeline support
- Enhanced Character Limits: Dynamic character count display showing actual instance limits (e.g., "21/3000")
- Post Visibility Display: See post visibility levels (Public, Unlisted, Followers-only, Direct) in timeline
- User Interaction Status: Visual indicators showing your favorited, boosted, and bookmarked posts in timeline
- Extended Sound Events: Comprehensive audio feedback for social actions including block, bookmark, delete, and undo operations
Audio System
Bifrost includes a sophisticated sound system with intelligent notification handling:
- Smart Notification System: Distinguishes between your own content and external notifications
- Immediate External Alerts: Never miss mentions, DMs, or replies from others, even during your own actions
- Context-Aware Sounds: Different sounds for mentions, direct messages, boosts, and timeline updates
- No Sound Spam: Prevents redundant sounds from your own posts while preserving important notifications
- Soundpack Manager: Secure HTTPS-based repository system
- Repository Management: Add/remove soundpack repositories with validation
- One-click Installation: Download, validate, and install soundpacks securely
- Customizable Sound Packs: Themed audio notifications (Default pack included)
- Audio Feedback: Sound events for all major actions and notifications
- Simple Volume Control: Single volume setting for all sound pack audio
- Easy Disable: Select "None" sound pack to disable all sounds
- Cross-platform Audio Support: Works on Linux, Windows, and macOS
Compose Features
- Mention Autocomplete: Type
@
to get suggestions from followers/following/search - Full Fediverse Handles: Completes to full format (@user@instance.com)
- Emoji Autocomplete: Type
:
to search 5,000+ Unicode emojis - Keyword Search: Find emojis by typing keywords (
:fire
,:heart
,:grin
) - Dynamic Character Count: Real-time display with actual instance limits (e.g., "21/3000")
- Content Warnings: Optional spoiler text support
- Visibility Controls: Public, Unlisted, Followers-only, or Direct messages
- Poll Creation: Add polls with up to 4 options, single or multiple choice, with expiration times
- Media Attachments: Upload images, videos, and audio with server limit validation
- Alt Text Support: Mandatory accessibility descriptions for uploaded media
- File Validation: MIME type and size checking with user-friendly error messages
Recent Updates (August 2025)
- Enhanced Unicode Support: Fixed display of apostrophes, quotes, and other special characters in posts using proper HTML entity decoding
- Persistent Timeline Filters: Timeline filter settings (show/hide replies, boosts, mentions, etc.) now persist across application restarts
- Robust Filter System: Fixed issue where reblog filters would stop working after timeline updates - all post loading paths now properly apply filters
- Improved Soundpack System: Enhanced soundpack installation validation and user experience with proper XDG directory handling
Technology Stack
- PySide6: Main GUI framework for proven accessibility
- ActivityPub: Full federation protocol support
- simpleaudio: Cross-platform audio with subprocess fallback
- Plyer: Cross-platform desktop notifications
- emoji: Comprehensive Unicode emoji library (5,000+ emojis)
- numpy: Audio processing for volume control and sound manipulation
- XDG Base Directory: Standards-compliant configuration storage
Keyboard Shortcuts
Timeline Navigation
- Ctrl+1: Switch to Home timeline
- Ctrl+2: Switch to Messages/DM timeline
- Ctrl+3: Switch to Mentions/Notifications timeline
- Ctrl+4: Switch to Local timeline
- Ctrl+5: Switch to Federated timeline
- Ctrl+6: Switch to Bookmarks timeline
- Ctrl+7: Switch to Followers timeline
- Ctrl+8: Switch to Following timeline
- Ctrl+9: Switch to Blocked Users timeline
- Ctrl+0: Switch to Muted Users timeline
- Ctrl+Tab: Switch between timeline tabs
- F5: Refresh current timeline
Post Actions
- Ctrl+N: Compose new post
- Ctrl+R: Reply to selected post
- Ctrl+B: Boost/reblog selected post
- Ctrl+F: Favorite selected post
- Ctrl+C: Copy selected post to clipboard
- Ctrl+U: Open URLs from selected post in browser
- Ctrl+Shift+E: Edit selected post (your own posts only)
- Shift+Delete: Delete selected post (your own posts only)
- Ctrl+Shift+B: Block user who authored selected post
- Ctrl+Shift+M: Mute user who authored selected post
- Applications Key/Shift+F10: Open context menu with all post actions
Navigation
- Arrow Keys: Navigate through posts
- Right Arrow: Expand thread / Move to first child when expanded
- Left Arrow: Collapse thread / Move to parent
- Shift+Left Arrow: Navigate to thread root from any reply
- Page Up/Down: Jump multiple posts
- Home/End: Go to first/last post
- Enter: Expand/collapse threads, vote in polls, or view post details
- Tab: Move between interface elements
Compose Dialog
- Ctrl+Enter: Send post
- @: Trigger mention autocomplete
- :: Trigger emoji autocomplete
- Arrow Keys: Navigate autocomplete suggestions
- Enter/Tab: Accept selected completion
- Escape: Close autocomplete or cancel compose
Application
- Ctrl+S: Open Search dialog
- Ctrl+Shift+F: Open Timeline Filters dialog
- Ctrl+,: Open Settings
- Ctrl+Shift+A: Add new account
- Ctrl+Alt+E: Edit your profile
- Ctrl+L: Open List Manager
- Ctrl+Alt+S: Open Soundpack Manager
- Ctrl+Q: Quit application
Installation
git clone <repository>
cd bifrost
pip install -r requirements.txt
python bifrost.py
Or on Arch Linux:
sudo pacman -S python-pyside6 python-requests python-simpleaudio python-emoji
yay -S python-plyer
Debug Logging System
Bifrost includes a comprehensive logging system for debugging and troubleshooting. This is especially valuable since the project is developed entirely by AI and requires excellent diagnostic capabilities.
Debug Modes
Console Debugging:
python bifrost.py -d
Shows debug output in the terminal with real-time logging.
File Debugging:
python bifrost.py -d debug.log
Saves all debug output to the specified file for later analysis.
Production Mode (Default):
python bifrost.py
Only shows warnings and errors to stderr.
Log Format
All log entries use the format: message - severity - timestamp
Example:
Timeline refresh requested: auto_refresh - DEBUG - 2025-07-22 23:17:33
New content detected: newest post changed from abc123 to def456 - INFO - 2025-07-22 23:17:34
Playing timeline_update sound for home timeline - INFO - 2025-07-22 23:17:34
Playing sound: timeline_update from /path/to/sound.wav at volume 100 - INFO - 2025-07-22 23:17:34
What Gets Logged
Application Lifecycle:
- Startup and shutdown events
- Window creation and display
- Settings initialization
- Account management operations
Timeline Operations:
- Auto-refresh timing and triggers
- New content detection
- Timeline switching
- Thread expansion/collapse
Sound System:
- Which sounds are played and when
- Sound pack loading and switching
- Audio playback success/failure
- Volume and file path information
Network Activity:
- ActivityPub API requests
- Streaming connection attempts
- Server capability detection
- Authentication operations
User Interactions:
- Post composition and sending
- Reply, boost, and favorite actions
- Menu and keyboard shortcut usage
- Timeline navigation
Error Handling:
- Network failures and timeouts
- API errors and invalid responses
- Audio playback issues
- File system problems
Debug Use Cases
Auto-refresh Issues:
python bifrost.py -d | grep -i refresh
See exactly when refreshes are triggered and why they might fail.
Sound Problems:
python bifrost.py -d | grep -i "sound\|audio"
Track which sounds are played and identify audio system issues.
Network Debugging:
python bifrost.py -d debug.log
# Then examine debug.log for ActivityPub and streaming logs
New Content Detection:
python bifrost.py -d | grep -i "new content\|external content\|user.*own content"
See when new posts are detected, whether they're from you or others, and why specific sounds are played.
Log Levels
- DEBUG: Detailed execution flow (timing, state changes, method calls)
- INFO: Important events (new content, sounds played, operations completed)
- WARNING: Recoverable issues (fallback operations, missing optional features)
- ERROR: Serious problems (network failures, invalid data, system errors)
- CRITICAL: Fatal issues that prevent operation
This logging system enables effective troubleshooting of any issues that arise during development or use.
Poll Features
Bifrost includes comprehensive poll support with full accessibility:
Creating Polls
- In Compose Dialog: Check "Add Poll" to create polls with your posts
- Up to 4 Options: Add 2-4 poll options (minimum 2 required)
- Choice Types: Single choice (radio buttons) or multiple choice (checkboxes)
- Expiration: Set when the poll expires (1 hour to 30 days)
- Real-time Validation: Get immediate feedback on poll requirements
Voting in Polls
- Accessible Discovery: Polls announced as "Poll: X options, Y votes, press Enter to vote"
- Keyboard Voting: Use Tab and arrow keys to navigate options, Space to select
- Radio Button Groups: Single choice polls use accessible radio button navigation
- Checkbox Lists: Multiple choice polls use standard checkbox interaction
- Vote Submission: Submit votes with accessible button controls
Viewing Results
- Integrated Display: Poll results shown in post details dialog as first tab
- Automatic Display: Results shown immediately after voting or for expired polls
- Navigable List: Vote counts and percentages in an accessible list widget
- Arrow Key Navigation: Review each option's results individually
- Clear Information: Format like "Option 1: 5 votes (41.7%)"
Poll Accessibility Features
- Screen Reader Support: Full compatibility with Orca, NVDA, and other screen readers
- Keyboard Only: Complete functionality without mouse interaction
- Clear Announcements: Descriptive text for poll status and options
- Focus Management: Proper tab order and focus placement
- Accessible Results: Poll results displayed using accessible QListWidget pattern
- Context Menu Support: All poll actions available via context menu shortcuts
- Error Handling: Accessible feedback for voting errors (duplicate votes, etc.)
Search Features
Bifrost includes comprehensive search functionality accessible via Ctrl+S:
Search Types
- All: Search across users, posts, and hashtags simultaneously
- Users: Find fediverse users by username or display name
- Posts: Search post content across the fediverse
- Hashtags: Discover trending and relevant hashtags
Search Interface
- Accessible Design: Full keyboard navigation and screen reader support
- Tabbed Results: Separate tabs for Users, Posts, and Hashtags with result counts
- Background Processing: Non-blocking search with progress indication
- Detailed Results: Rich information display for each result type
User Search Results
- Display format: "@username@instance.com - Display Name"
- Double-click to view user profiles (integration with profile viewer)
- Shows follower/following counts and bio information
Post Search Results
- Shows author and content preview
- Double-click to view full post details
- Integrates with existing post interaction features
Hashtag Search Results
- Displays hashtag usage statistics and trends
- Shows recent usage counts for popular hashtags
- Enables hashtag discovery for improved post reach
Timeline Filtering
Customize your timeline experience with Ctrl+Shift+F:
Content Type Filters
- Show Replies: Toggle visibility of reply posts
- Show Boosts: Control whether reblogged/boosted posts appear
- Show Mentions: Filter posts that mention your username
Media Content Filters
- Media Only: Show only posts with images, videos, or audio attachments
- Text Only: Show only posts without any media attachments
- Mutual Exclusion: Media and text filters cannot be active simultaneously
Keyword and Emoji Filtering
- Blocked Keywords: Hide posts containing specific words, phrases, or emojis
- Copy-Paste Support: Simply paste emojis (🔥, 💯, etc.) or type keywords to block
- Case Insensitive: Filtering works regardless of text capitalization
- Content Warning Check: Also filters posts where keywords appear in content warnings
- Easy Management: Add keywords by typing and pressing Enter, remove by selecting and clicking Remove
Filter Features
- Real-time Application: Changes apply immediately to current timeline
- Timeline Specific: Filters apply to Home, Local, and Federated timelines
- Persistent Settings: Filter preferences are remembered across sessions
- Accessible Interface: Full keyboard navigation and clear descriptions
- Reset Option: Quick reset to default filter settings
List Management
Bifrost includes comprehensive list management functionality accessible via Ctrl+L:
Creating and Managing Lists
- List Creation: Create custom lists with descriptive titles and configurable replies policies
- List Editing: Modify list titles and replies behavior after creation
- List Deletion: Remove lists with confirmation dialog for safety
- Accessible Interface: Full keyboard navigation with clear announcements
List Member Management
- Add Members: Add accounts from your followed accounts to lists with search functionality
- Remove Members: Remove accounts from lists with multi-selection support
- Search Integration: Filter followed accounts by name or username when adding to lists
- Real-time Updates: Member lists update immediately after modifications
List Timelines
- Dedicated Timeline Access: View list timelines through the Lists submenu in main window
- Dynamic Menu: Lists submenu automatically updates when lists are created or deleted
- Focused Content: See posts only from accounts in specific lists
- Timeline Integration: List timelines work with all existing timeline features (refresh, pagination, etc.)
List Features
- Replies Policy Control: Configure whether to show replies to list members, followed accounts, or no replies
- Background Operations: All list operations use background threading for responsive UI
- Error Handling: Comprehensive error handling with accessible feedback
- Multi-selection Support: Select multiple accounts when adding or removing list members
- Validation: Input validation ensures lists have proper titles and configuration
Accessibility Features
- Complete keyboard navigation
- Proper screen reader announcements
- Focus management and tab order
- Accessible names and descriptions for all controls
- Thread expansion/collapse with audio feedback
- Poll creation and voting with full accessibility support
- Context menu support with Applications key and Shift+F10
- Accessible content display using QTextEdit for complex information
- Private message conversations with proper threading
Known Qt Display Quirk
Due to a Qt tree widget display synchronization issue, thread collapse may occasionally require a double-operation for the visual display to fully sync:
If collapse appears incomplete:
- Navigate to thread root post (use Shift+Left from any reply)
- Press Left to collapse → announces "collapsed"
- Press Right then Left again → now fully collapsed visually
Note: Navigation logic works correctly after the first collapse (arrow keys will skip collapsed replies), but the visual display may need the extra cycle to sync.
Sound Pack Creation and Installation
Creating Custom Sound Packs
Sound packs in Bifrost allow you to customize the audio feedback for different events. Each sound pack consists of a directory containing audio files and a configuration file.
Sound Pack Structure
A sound pack must contain:
- pack.json - Configuration file with metadata and sound mappings
- Audio files - WAV or OGG files for each sound event
Required Sound Events
Your sound pack should include audio files for these events:
private_message
- Direct message receivedmention
- User mentioned in postboost
- Post boosted/rebloggedreply
- Reply to user's postpost_sent
- User successfully postedtimeline_update
- New posts in timelinenotification
- General notificationautocomplete
- Autocomplete suggestions available (optional)autocomplete_end
- Autocomplete interaction ended (optional)startup
- Application started (optional)shutdown
- Application closing (optional)expand
- Thread expanded (optional)collapse
- Thread collapsed (optional)success
- General success feedback (optional)error
- Error occurred (optional)block
- User blocked (optional)unblock
- User unblocked (optional)bookmark
- Post bookmarked (optional)unbookmark
- Post unbookmarked (optional)unfavorite
- Post unfavorited (optional)unboost
- Post unboosted (optional)delete_post
- Post deleted (optional)
Creating pack.json
Create a pack.json
file with this format:
{
"name": "My Custom Pack",
"description": "A description of your sound pack",
"author": "Your Name",
"version": "1.0",
"sounds": {
"private_message": "dm.wav",
"mention": "mention.ogg",
"boost": "boost.wav",
"reply": "reply.wav",
"post_sent": "sent.wav",
"timeline_update": "update.wav",
"notification": "notification.wav",
"autocomplete": "autocomplete.wav",
"autocomplete_end": "autocomplete_end.wav",
"startup": "startup.wav",
"shutdown": "shutdown.wav",
"expand": "expand.wav",
"collapse": "collapse.wav",
"success": "success.wav",
"error": "error.wav"
}
}
Audio File Requirements
- Formats: WAV or OGG Vorbis only
- Size: Maximum 10MB per file
- Duration: Keep sounds short (1-3 seconds recommended)
- Quality: 44.1kHz, 16-bit recommended for WAV files
Example Directory Structure
MyPack/
├── pack.json
├── dm.wav
├── mention.ogg
├── boost.wav
├── reply.wav
├── sent.wav
├── update.wav
├── notification.wav
├── startup.wav
├── shutdown.wav
├── expand.wav
├── collapse.wav
├── success.wav
└── error.wav
Installing Sound Packs
Method 1: Manual Installation
- Create your sound pack directory structure as shown above
- Copy the directory to
~/.local/share/bifrost/sounds/
- Restart Bifrost or go to Settings → Audio to select the new pack
Method 2: ZIP Installation
-
Create ZIP file correctly:
- Navigate to your sound pack directory
- Select ALL files (pack.json and audio files)
- Create a ZIP file containing just the files, NOT the folder
- Important: The ZIP should contain
pack.json
at the root, notMyPack/pack.json
-
Install via Soundpack Manager:
- Open Bifrost
- Press Ctrl+Alt+S to open Soundpack Manager
- Click "Install from ZIP file"
- Select your ZIP file
- The soundpack will be validated and installed automatically
Method 3: Repository Installation
If you have access to a soundpack repository:
- Open Soundpack Manager (Ctrl+Alt+S)
- Browse available soundpacks from configured repositories
- Click "Install" next to the desired soundpack
- The soundpack will download and install automatically
ZIP File Creation Tips
Correct ZIP structure:
soundpack.zip
├── pack.json
├── dm.wav
├── mention.ogg
└── other_audio_files...
Incorrect ZIP structure (will fail):
soundpack.zip
└── MyPack/
├── pack.json
├── dm.wav
└── other_files...
Common Commands for ZIP Creation
Linux/macOS:
cd MyPack
zip -r ../MyPack.zip *
Windows (PowerShell):
cd MyPack
Compress-Archive -Path * -DestinationPath ..\MyPack.zip
Troubleshooting
- "Invalid filename in archive": Ensure filenames only contain letters, numbers, dots, dashes, and underscores
- "No valid audio files found": Check that you have WAV or OGG files and they're properly formatted
- "Invalid pack.json format": Verify your JSON syntax and required fields (name, sounds)
- Installation fails: Make sure you zipped the files themselves, not the containing folder
Sound Pack Security
Bifrost's soundpack system includes security measures:
- Maximum file sizes (10MB per file, 50MB total download)
- File type validation (only WAV/OGG audio files allowed)
- Path sanitization (prevents directory traversal attacks)
- Repository validation (HTTPS required for remote repositories)
Contributing
This is a vibe coding project where AI handles implementation. Human contributors can:
- Test accessibility with different screen readers
- Suggest features and improvements
- Create new sound packs (see Sound Pack Creation section above)
- Report bugs and usability issues
License
This project demonstrates the potential of human-AI collaboration in creating accessible software. It is released under the gpl version 3. See LICENSE file for details.