minor improvements and fixes
This commit is contained in:
parent
c7bf7b9007
commit
598b37953e
3 changed files with 110 additions and 54 deletions
|
|
@ -13,7 +13,7 @@ class VersionInfoModal(QDialog):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setWindowTitle("What's New in SoulSync v0.5")
|
self.setWindowTitle("What's New in SoulSync v0.51")
|
||||||
self.setModal(True)
|
self.setModal(True)
|
||||||
self.setFixedSize(600, 500)
|
self.setFixedSize(600, 500)
|
||||||
self.setup_ui()
|
self.setup_ui()
|
||||||
|
|
@ -68,7 +68,7 @@ class VersionInfoModal(QDialog):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# Version subtitle
|
# Version subtitle
|
||||||
version_subtitle = QLabel("Version 0.5 - Latest Features & Improvements")
|
version_subtitle = QLabel("Version 0.51 - Latest Features & Improvements")
|
||||||
version_subtitle.setFont(QFont("SF Pro Text", 11, QFont.Weight.Medium))
|
version_subtitle.setFont(QFont("SF Pro Text", 11, QFont.Weight.Medium))
|
||||||
version_subtitle.setStyleSheet("""
|
version_subtitle.setStyleSheet("""
|
||||||
color: rgba(255, 255, 255, 0.7);
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
|
@ -112,63 +112,50 @@ class VersionInfoModal(QDialog):
|
||||||
content_layout.setContentsMargins(30, 25, 30, 25)
|
content_layout.setContentsMargins(30, 25, 30, 25)
|
||||||
content_layout.setSpacing(25)
|
content_layout.setSpacing(25)
|
||||||
|
|
||||||
# New Watchlist Feature
|
# Settings Page Improvements
|
||||||
watchlist_section = self.create_feature_section(
|
settings_section = self.create_feature_section(
|
||||||
"🔍 New Watchlist Feature",
|
"⚙️ Settings Page Improvements",
|
||||||
"Track your favorite artists and get notified when they release new music",
|
"Enhanced settings interface for better usability and visual consistency",
|
||||||
[
|
[
|
||||||
"• Automatically monitors your favorite artists for new releases",
|
"• Added vertical scrolling support for better usability on small screens",
|
||||||
"• Smart scanning that checks only for releases since last scan",
|
"• Cleaned up text backgrounds throughout settings for better visual consistency",
|
||||||
"• Real-time progress tracking with detailed status indicators",
|
"• Applied consistent green monospace styling to log file path display",
|
||||||
"• Seamless integration with your existing music library",
|
"• Added rounded corners to API configuration frames (Spotify, Plex, Soulseek)",
|
||||||
"• Configurable scan intervals (now every 10 minutes for faster updates)",
|
"• Enhanced label styling with transparent backgrounds and proper white text"
|
||||||
"• Search functionality for managing large artist lists (200+ artists)",
|
]
|
||||||
"• Visual status icons showing scan recency and completion status"
|
)
|
||||||
],
|
content_layout.addWidget(settings_section)
|
||||||
"How to use: Go to the Artists page, click 'Add to Watchlist' on any artist card, then monitor progress in the new Watchlist Status modal accessible from the Dashboard."
|
|
||||||
|
# Watchlist System Enhancements
|
||||||
|
watchlist_section = self.create_feature_section(
|
||||||
|
"👀 Watchlist System Enhancements",
|
||||||
|
"Improved reliability and user experience for artist monitoring",
|
||||||
|
[
|
||||||
|
"• Enhanced rate limiting with comprehensive multi-layer protection to prevent API bans",
|
||||||
|
"• Increased delays between artists (2.0s) and albums (0.5s) for safer scanning",
|
||||||
|
"• Enhanced Spotify API interval timing and error handling",
|
||||||
|
"• Unified scan implementation - manual and auto scans now use same worker for consistency",
|
||||||
|
"• Fixed progress bars resetting when reopening modal during active scans",
|
||||||
|
"• Professional artist cards with improved visual hierarchy and spacing",
|
||||||
|
"• Modern hover effects and enhanced delete button styling"
|
||||||
|
]
|
||||||
)
|
)
|
||||||
content_layout.addWidget(watchlist_section)
|
content_layout.addWidget(watchlist_section)
|
||||||
|
|
||||||
# Enhanced Progress Tracking
|
# Artist Search Enhancements
|
||||||
progress_section = self.create_feature_section(
|
artist_section = self.create_feature_section(
|
||||||
"📊 Enhanced Progress Tracking",
|
"🎵 Artist Search Enhancements",
|
||||||
"Better visibility into your music scanning and download progress",
|
"Better visual feedback and improved navigation for artist discovery",
|
||||||
[
|
[
|
||||||
"• Three-progress-bar system for Singles/EPs, Albums, and Overall progress",
|
"• Added watchlist eye indicators (👁️) to artist search results",
|
||||||
"• Per-artist progress tracking that resets for each new artist",
|
"• Green eye icon appears in top-right corner for artists already in watchlist",
|
||||||
"• Real-time updates during scanning with detailed completion metrics",
|
"• Real-time updates when artists are added/removed from watchlist",
|
||||||
"• Smart release categorization (≤3 tracks = Single/EP, ≥4 tracks = Album)",
|
"• Enhanced horizontal scrolling with mouse wheel support for artist results",
|
||||||
"• Improved mathematical accuracy for progress calculations"
|
"• Smooth navigation through search results without manual scrollbar dragging"
|
||||||
]
|
],
|
||||||
|
"Look for the green eye icon (👁️) in artist search results to instantly see which artists you're already tracking!"
|
||||||
)
|
)
|
||||||
content_layout.addWidget(progress_section)
|
content_layout.addWidget(artist_section)
|
||||||
|
|
||||||
# Performance Improvements
|
|
||||||
performance_section = self.create_feature_section(
|
|
||||||
"⚡ Performance Improvements",
|
|
||||||
"Faster scanning and better resource management",
|
|
||||||
[
|
|
||||||
"• Reduced scan intervals from 60 minutes to 10 minutes",
|
|
||||||
"• Removed artificial 25-track processing limits",
|
|
||||||
"• Optimized database queries for better responsiveness",
|
|
||||||
"• Improved memory management during large scans"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
content_layout.addWidget(performance_section)
|
|
||||||
|
|
||||||
# UI/UX Enhancements
|
|
||||||
ui_section = self.create_feature_section(
|
|
||||||
"🎨 UI/UX Enhancements",
|
|
||||||
"Cleaner interface and better user experience",
|
|
||||||
[
|
|
||||||
"• Replaced confusing colored status circles with intuitive icons",
|
|
||||||
"• Added search functionality for large artist lists",
|
|
||||||
"• Smart display logic showing last 5 artists when no search active",
|
|
||||||
"• Removed unnecessary white borders for cleaner appearance",
|
|
||||||
"• Improved status indicators with meaningful visual feedback"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
content_layout.addWidget(ui_section)
|
|
||||||
|
|
||||||
scroll_area.setWidget(content_widget)
|
scroll_area.setWidget(content_widget)
|
||||||
return scroll_area
|
return scroll_area
|
||||||
|
|
|
||||||
|
|
@ -1167,6 +1167,7 @@ class ArtistResultCard(QFrame):
|
||||||
self.artist = artist_match.artist
|
self.artist = artist_match.artist
|
||||||
self.setup_ui()
|
self.setup_ui()
|
||||||
self.load_artist_image()
|
self.load_artist_image()
|
||||||
|
self.check_watchlist_status()
|
||||||
|
|
||||||
def setup_ui(self):
|
def setup_ui(self):
|
||||||
self.setFixedSize(200, 280)
|
self.setFixedSize(200, 280)
|
||||||
|
|
@ -1242,6 +1243,23 @@ class ArtistResultCard(QFrame):
|
||||||
followers_label.setStyleSheet("color: #b3b3b3; padding: 2px;")
|
followers_label.setStyleSheet("color: #b3b3b3; padding: 2px;")
|
||||||
followers_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
followers_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
|
||||||
|
# Watchlist eye indicator (positioned absolutely in top-right corner)
|
||||||
|
self.watchlist_indicator = QLabel(self)
|
||||||
|
self.watchlist_indicator.setText("👁️")
|
||||||
|
self.watchlist_indicator.setFont(QFont("Arial", 14))
|
||||||
|
self.watchlist_indicator.setFixedSize(24, 24)
|
||||||
|
self.watchlist_indicator.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
self.watchlist_indicator.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
background: rgba(29, 185, 84, 0.9);
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid rgba(29, 185, 84, 1);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
self.watchlist_indicator.move(168, 8) # Position in top-right corner
|
||||||
|
self.watchlist_indicator.hide() # Hidden by default
|
||||||
|
|
||||||
layout.addWidget(self.image_container, 0, Qt.AlignmentFlag.AlignCenter)
|
layout.addWidget(self.image_container, 0, Qt.AlignmentFlag.AlignCenter)
|
||||||
layout.addWidget(name_label)
|
layout.addWidget(name_label)
|
||||||
layout.addWidget(confidence_label)
|
layout.addWidget(confidence_label)
|
||||||
|
|
@ -1290,6 +1308,25 @@ class ArtistResultCard(QFrame):
|
||||||
"""Handle image load error"""
|
"""Handle image load error"""
|
||||||
print(f"Failed to load artist image: {error}")
|
print(f"Failed to load artist image: {error}")
|
||||||
|
|
||||||
|
def check_watchlist_status(self):
|
||||||
|
"""Check if this artist is in the watchlist and show eye indicator"""
|
||||||
|
try:
|
||||||
|
database = get_database()
|
||||||
|
is_watching = database.is_artist_in_watchlist(self.artist.id)
|
||||||
|
|
||||||
|
if is_watching:
|
||||||
|
self.watchlist_indicator.show()
|
||||||
|
else:
|
||||||
|
self.watchlist_indicator.hide()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error checking watchlist status for artist {self.artist.name}: {e}")
|
||||||
|
self.watchlist_indicator.hide()
|
||||||
|
|
||||||
|
def refresh_watchlist_status(self):
|
||||||
|
"""Refresh the watchlist indicator (call this when watchlist changes)"""
|
||||||
|
self.check_watchlist_status()
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
"""Handle click to select artist"""
|
"""Handle click to select artist"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -3455,6 +3492,21 @@ class ArtistsPage(QWidget):
|
||||||
self.artist_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
self.artist_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||||
self.artist_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
self.artist_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
||||||
self.artist_scroll.setFixedHeight(320) # Fixed height to accommodate artist cards
|
self.artist_scroll.setFixedHeight(320) # Fixed height to accommodate artist cards
|
||||||
|
|
||||||
|
# Enable horizontal scrolling with mouse wheel
|
||||||
|
def wheelEvent(event):
|
||||||
|
# Convert vertical wheel scrolling to horizontal scrolling
|
||||||
|
if event.angleDelta().y() != 0:
|
||||||
|
horizontal_scroll = self.artist_scroll.horizontalScrollBar()
|
||||||
|
current_value = horizontal_scroll.value()
|
||||||
|
# Scroll by artist card width (200px + spacing)
|
||||||
|
scroll_amount = -event.angleDelta().y() // 120 * 220 # Each wheel step scrolls ~1 card
|
||||||
|
horizontal_scroll.setValue(current_value + scroll_amount)
|
||||||
|
event.accept()
|
||||||
|
else:
|
||||||
|
QScrollArea.wheelEvent(self.artist_scroll, event)
|
||||||
|
|
||||||
|
self.artist_scroll.wheelEvent = wheelEvent
|
||||||
self.artist_scroll.setStyleSheet("""
|
self.artist_scroll.setStyleSheet("""
|
||||||
QScrollArea {
|
QScrollArea {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
@ -5122,6 +5174,8 @@ class ArtistsPage(QWidget):
|
||||||
self.update_watchlist_button(False)
|
self.update_watchlist_button(False)
|
||||||
# Emit signal to update dashboard button count
|
# Emit signal to update dashboard button count
|
||||||
self.database_updated_externally.emit()
|
self.database_updated_externally.emit()
|
||||||
|
# Refresh all artist card watchlist indicators
|
||||||
|
self.refresh_all_artist_card_watchlist_status()
|
||||||
if hasattr(self, 'toast_manager') and self.toast_manager:
|
if hasattr(self, 'toast_manager') and self.toast_manager:
|
||||||
self.toast_manager.success(f"Removed {artist_name} from watchlist")
|
self.toast_manager.success(f"Removed {artist_name} from watchlist")
|
||||||
else:
|
else:
|
||||||
|
|
@ -5134,6 +5188,8 @@ class ArtistsPage(QWidget):
|
||||||
self.update_watchlist_button(True)
|
self.update_watchlist_button(True)
|
||||||
# Emit signal to update dashboard button count
|
# Emit signal to update dashboard button count
|
||||||
self.database_updated_externally.emit()
|
self.database_updated_externally.emit()
|
||||||
|
# Refresh all artist card watchlist indicators
|
||||||
|
self.refresh_all_artist_card_watchlist_status()
|
||||||
if hasattr(self, 'toast_manager') and self.toast_manager:
|
if hasattr(self, 'toast_manager') and self.toast_manager:
|
||||||
self.toast_manager.success(f"Added {artist_name} to watchlist")
|
self.toast_manager.success(f"Added {artist_name} to watchlist")
|
||||||
else:
|
else:
|
||||||
|
|
@ -5145,6 +5201,19 @@ class ArtistsPage(QWidget):
|
||||||
if hasattr(self, 'toast_manager') and self.toast_manager:
|
if hasattr(self, 'toast_manager') and self.toast_manager:
|
||||||
self.toast_manager.error("Error updating watchlist")
|
self.toast_manager.error("Error updating watchlist")
|
||||||
|
|
||||||
|
def refresh_all_artist_card_watchlist_status(self):
|
||||||
|
"""Refresh watchlist indicators on all visible artist cards"""
|
||||||
|
try:
|
||||||
|
# Find all artist cards in the search results layout
|
||||||
|
for i in range(self.artist_results_layout.count()):
|
||||||
|
item = self.artist_results_layout.itemAt(i)
|
||||||
|
if item and item.widget():
|
||||||
|
widget = item.widget()
|
||||||
|
if isinstance(widget, ArtistResultCard):
|
||||||
|
widget.refresh_watchlist_status()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error refreshing artist card watchlist status: {e}")
|
||||||
|
|
||||||
def update_watchlist_button(self, is_watching):
|
def update_watchlist_button(self, is_watching):
|
||||||
"""Update watchlist button appearance based on watching status"""
|
"""Update watchlist button appearance based on watching status"""
|
||||||
if is_watching:
|
if is_watching:
|
||||||
|
|
|
||||||
|
|
@ -1240,7 +1240,7 @@ class ModernSidebar(QWidget):
|
||||||
layout.setSpacing(0)
|
layout.setSpacing(0)
|
||||||
|
|
||||||
# Version button (clickable)
|
# Version button (clickable)
|
||||||
self.version_button = QPushButton("v.0.5")
|
self.version_button = QPushButton("v.0.51")
|
||||||
self.version_button.setFont(QFont("SF Pro Text", 10, QFont.Weight.Medium))
|
self.version_button.setFont(QFont("SF Pro Text", 10, QFont.Weight.Medium))
|
||||||
self.version_button.setCursor(Qt.CursorShape.PointingHandCursor)
|
self.version_button.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
self.version_button.setStyleSheet("""
|
self.version_button.setStyleSheet("""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue