Fix multiple notification and UI bugs to improve user experience
- Fix priority-based notification sounds to prevent mentions playing timeline update sounds - Fix reply functionality to use full @username@domain.com format for proper federation - Fix missing reply sound notifications by adding reply to priority system - Fix duplicate reply count display to prevent "(1 replies) (2 replies)" accumulation - Fix poll voting to automatically refresh timeline and prevent duplicate vote attempts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -316,7 +316,13 @@ class AccessibleTreeWidget(QTreeWidget):
|
||||
if item.childCount() > 0:
|
||||
original_text = item.text(0)
|
||||
child_count = item.childCount()
|
||||
accessible_text = f"{original_text} ({child_count} replies, {state})"
|
||||
|
||||
# Remove any existing reply count information to prevent duplication
|
||||
# Pattern matches " (X replies, collapsed/expanded)" at the end of text
|
||||
import re
|
||||
clean_text = re.sub(r' \(\d+ replies?, (?:collapsed|expanded)\)$', '', original_text)
|
||||
|
||||
accessible_text = f"{clean_text} ({child_count} replies, {state})"
|
||||
item.setData(0, Qt.AccessibleTextRole, accessible_text)
|
||||
|
||||
# Emit signal for potential sound feedback
|
||||
|
@ -631,8 +631,8 @@ class MainWindow(QMainWindow):
|
||||
def reply_to_post(self, post):
|
||||
"""Reply to a specific post"""
|
||||
dialog = ComposeDialog(self.account_manager, self)
|
||||
# Pre-fill with reply mention
|
||||
dialog.text_edit.setPlainText(f"@{post.account.username} ")
|
||||
# Pre-fill with reply mention using full fediverse handle
|
||||
dialog.text_edit.setPlainText(f"@{post.account.acct} ")
|
||||
# Move cursor to end
|
||||
cursor = dialog.text_edit.textCursor()
|
||||
cursor.movePosition(QTextCursor.MoveOperation.End)
|
||||
|
@ -163,11 +163,17 @@ class TimelineView(AccessibleTreeWidget):
|
||||
|
||||
if self.timeline_type == "notifications":
|
||||
# Handle notifications data structure
|
||||
# Track notification types to determine priority-based sound
|
||||
notification_types_found = set()
|
||||
|
||||
for notification_data in timeline_data:
|
||||
try:
|
||||
notification_type = notification_data['type']
|
||||
sender = notification_data['account']['display_name'] or notification_data['account']['username']
|
||||
|
||||
# Track notification types for priority-based sound selection
|
||||
notification_types_found.add(notification_type)
|
||||
|
||||
# Notifications with status (mentions, boosts, favorites)
|
||||
if 'status' in notification_data:
|
||||
post = Post.from_api_dict(notification_data['status'])
|
||||
@ -182,21 +188,21 @@ class TimelineView(AccessibleTreeWidget):
|
||||
|
||||
if notification_type == 'mention':
|
||||
self.notification_manager.notify_mention(sender, content_preview)
|
||||
self.sound_manager.play_mention()
|
||||
elif notification_type == 'reblog':
|
||||
self.notification_manager.notify_boost(sender, content_preview)
|
||||
self.sound_manager.play_boost()
|
||||
elif notification_type == 'favourite':
|
||||
self.notification_manager.notify_favorite(sender, content_preview)
|
||||
self.sound_manager.play_favorite()
|
||||
elif notification_type == 'follow':
|
||||
# Handle follow notifications without status (skip if initial load)
|
||||
if not self.skip_notifications:
|
||||
self.notification_manager.notify_follow(sender)
|
||||
self.sound_manager.play_follow()
|
||||
except Exception as e:
|
||||
print(f"Error parsing notification: {e}")
|
||||
continue
|
||||
|
||||
# Play priority-based sound for notification batch (skip if initial load)
|
||||
if notification_types_found and not self.skip_notifications:
|
||||
self._play_priority_notification_sound(notification_types_found)
|
||||
elif self.timeline_type == "conversations":
|
||||
# Handle conversations data structure
|
||||
for conv_data in timeline_data:
|
||||
@ -1056,6 +1062,10 @@ class TimelineView(AccessibleTreeWidget):
|
||||
# Play success sound
|
||||
self.sound_manager.play_success()
|
||||
|
||||
# Refresh the entire timeline to ensure poll state is properly updated
|
||||
# and prevent duplicate voting attempts
|
||||
self.refresh()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to submit poll vote: {e}")
|
||||
# Play error sound
|
||||
@ -1196,4 +1206,52 @@ class TimelineView(AccessibleTreeWidget):
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to show post details: {e}")
|
||||
self.sound_manager.play_error()
|
||||
self.sound_manager.play_error()
|
||||
|
||||
def _play_priority_notification_sound(self, notification_types):
|
||||
"""Play the highest priority sound from a set of notification types.
|
||||
|
||||
Priority order (highest to lowest):
|
||||
1. direct_message (direct messages)
|
||||
2. follow (follow notifications)
|
||||
3. mention (mentions)
|
||||
4. reply (replies to user's posts)
|
||||
4. reblog (boosts)
|
||||
5. favourite (favorites)
|
||||
"""
|
||||
# Define priority order (higher number = higher priority)
|
||||
priority_map = {
|
||||
'direct_message': 5,
|
||||
'follow': 4,
|
||||
'mention': 3,
|
||||
'reply': 2, # Reply notifications should play reply sound
|
||||
'reblog': 2,
|
||||
'favourite': 1
|
||||
}
|
||||
|
||||
# Find the highest priority notification type
|
||||
highest_priority = 0
|
||||
highest_type = None
|
||||
|
||||
for notification_type in notification_types:
|
||||
priority = priority_map.get(notification_type, 0)
|
||||
if priority > highest_priority:
|
||||
highest_priority = priority
|
||||
highest_type = notification_type
|
||||
|
||||
# Play appropriate sound for highest priority notification
|
||||
if highest_type == 'direct_message':
|
||||
self.sound_manager.play_direct_message()
|
||||
elif highest_type == 'follow':
|
||||
self.sound_manager.play_follow()
|
||||
elif highest_type == 'mention':
|
||||
self.sound_manager.play_mention()
|
||||
elif highest_type == 'reply':
|
||||
self.sound_manager.play_reply()
|
||||
elif highest_type == 'reblog':
|
||||
self.sound_manager.play_boost()
|
||||
elif highest_type == 'favourite':
|
||||
self.sound_manager.play_favorite()
|
||||
else:
|
||||
# Fallback for unknown notification types
|
||||
self.sound_manager.play_notification()
|
Reference in New Issue
Block a user