Add comprehensive social features with accessibility-first design
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>
This commit is contained in:
@@ -244,6 +244,33 @@ class ActivityPubClient:
|
||||
def get_custom_emojis(self) -> List[Dict]:
|
||||
"""Get custom emojis for this instance"""
|
||||
return self._make_request('GET', '/api/v1/custom_emojis')
|
||||
|
||||
def edit_status(self, status_id: str, content: str, visibility: str = 'public',
|
||||
content_warning: Optional[str] = None,
|
||||
media_ids: Optional[List[str]] = None,
|
||||
content_type: str = 'text/plain') -> Dict:
|
||||
"""Edit an existing status"""
|
||||
data = {
|
||||
'status': content,
|
||||
'visibility': visibility
|
||||
}
|
||||
|
||||
if content_type == 'text/markdown':
|
||||
data['content_type'] = 'text/markdown'
|
||||
|
||||
if content_warning:
|
||||
data['spoiler_text'] = content_warning
|
||||
if media_ids:
|
||||
data['media_ids'] = media_ids
|
||||
|
||||
endpoint = f'/api/v1/statuses/{status_id}'
|
||||
return self._make_request('PUT', endpoint, data=data)
|
||||
|
||||
def get_relationship(self, account_id: str) -> Dict:
|
||||
"""Get relationship with an account"""
|
||||
params = {'id': account_id}
|
||||
result = self._make_request('GET', '/api/v1/accounts/relationships', params=params)
|
||||
return result[0] if result else {}
|
||||
|
||||
|
||||
class AuthenticationError(Exception):
|
||||
|
Reference in New Issue
Block a user