Sync from development - prepare for v0.2.0.7

This commit is contained in:
Omni
2025-12-28 22:17:44 +00:00
parent 99fb369d5e
commit 5869a896a8
8 changed files with 46 additions and 25 deletions

View File

@@ -1,16 +1,31 @@
# Jackify Changelog # Jackify Changelog
## v0.2.0.7 - Critical Auth Fix
**Release Date:** 2025-12-28
### Critical Bug Fixes
- **OAuth Token Loss**: Fixed version comparison bug that was deleting OAuth tokens every time settings were saved (affects users on v0.2.0.4+)
- Fixed internal import paths for improved stability
---
## v0.2.0.6 - Premium Detection and Engine Update ## v0.2.0.6 - Premium Detection and Engine Update
**Release Date:** 2025-12-28 **Release Date:** 2025-12-28
**IMPORTANT:** If you are on v0.2.0.5, automatic updates will not work. You must manually download and install v0.2.0.6.
### Engine Updates ### Engine Updates
- **jackify-engine 0.4.4**: Latest engine version with improvements - **jackify-engine 0.4.4**: Latest engine version with improvements
### Critical Bug Fixes ### Critical Bug Fixes
- **Auto-Update System**: Fixed broken update dialog import that prevented automatic updates
- **Premium Detection**: Fixed false Premium errors caused by overly-broad detection pattern triggering on jackify-engine 0.4.3's userinfo JSON output - **Premium Detection**: Fixed false Premium errors caused by overly-broad detection pattern triggering on jackify-engine 0.4.3's userinfo JSON output
- **Custom Data Directory**: Fixed AppImage always creating ~/Jackify on startup, even when user configured a custom jackify_data_dir - **Custom Data Directory**: Fixed AppImage always creating ~/Jackify on startup, even when user configured a custom jackify_data_dir
- **Proton Auto-Selection**: Fixed auto-selection writing invalid "auto" string to config on detection failure - **Proton Auto-Selection**: Fixed auto-selection writing invalid "auto" string to config on detection failure
### Quality Improvements
- Added pre-build import validator to prevent broken imports from reaching production
--- ---
## v0.2.0.5 - Emergency OAuth Fix ## v0.2.0.5 - Emergency OAuth Fix

View File

@@ -5,4 +5,4 @@ This package provides both CLI and GUI interfaces for managing
Wabbajack modlists natively on Linux systems. Wabbajack modlists natively on Linux systems.
""" """
__version__ = "0.2.0.6" __version__ = "0.2.0.7"

View File

@@ -157,7 +157,8 @@ class ConfigHandler:
# Migration: v0.0.x -> v0.2.0 # Migration: v0.0.x -> v0.2.0
# Encryption changed from cryptography (Fernet) to pycryptodome (AES-GCM) # Encryption changed from cryptography (Fernet) to pycryptodome (AES-GCM)
# Old encrypted API keys cannot be decrypted, must be re-entered # Old encrypted API keys cannot be decrypted, must be re-entered
if current_version < "0.2.0": from packaging import version
if version.parse(current_version) < version.parse("0.2.0"):
# Clear old encrypted credentials # Clear old encrypted credentials
if self.settings.get("nexus_api_key"): if self.settings.get("nexus_api_key"):
logger.warning("Clearing saved API key due to encryption format change") logger.warning("Clearing saved API key due to encryption format change")

View File

@@ -205,8 +205,8 @@ class ShortcutHandler:
time.sleep(1) # Give some time for the install to complete time.sleep(1) # Give some time for the install to complete
# Now import it # Now import it
import steam_vdf import vdf as steam_vdf
with open(shortcuts_file, 'rb') as f: with open(shortcuts_file, 'rb') as f:
shortcuts_data = steam_vdf.load(f) shortcuts_data = steam_vdf.load(f)

View File

@@ -1562,7 +1562,7 @@ class JackifyMainWindow(QMainWindow):
# Show update dialog after a short delay to ensure GUI is fully loaded # Show update dialog after a short delay to ensure GUI is fully loaded
def show_update_dialog(): def show_update_dialog():
from ..dialogs.update_dialog import UpdateDialog from .dialogs.update_dialog import UpdateDialog
dialog = UpdateDialog(update_info, self.update_service, self) dialog = UpdateDialog(update_info, self.update_service, self)
dialog.exec() dialog.exec()

View File

@@ -4358,7 +4358,7 @@ class InstallModlistScreen(QWidget):
def _show_somnium_post_install_guidance(self): def _show_somnium_post_install_guidance(self):
"""Show guidance popup for Somnium post-installation steps""" """Show guidance popup for Somnium post-installation steps"""
from ..widgets.message_service import MessageService from ..services.message_service import MessageService
guidance_text = f"""<b>Somnium Post-Installation Required</b><br><br> guidance_text = f"""<b>Somnium Post-Installation Required</b><br><br>
Due to Somnium's non-standard folder structure, you need to manually update the binary paths in ModOrganizer:<br><br> Due to Somnium's non-standard folder structure, you need to manually update the binary paths in ModOrganizer:<br><br>

View File

@@ -3494,7 +3494,7 @@ class InstallTTWScreen(QWidget):
def _show_somnium_post_install_guidance(self): def _show_somnium_post_install_guidance(self):
"""Show guidance popup for Somnium post-installation steps""" """Show guidance popup for Somnium post-installation steps"""
from ..widgets.message_service import MessageService from ..services.message_service import MessageService
guidance_text = f"""<b>Somnium Post-Installation Required</b><br><br> guidance_text = f"""<b>Somnium Post-Installation Required</b><br><br>
Due to Somnium's non-standard folder structure, you need to manually update the binary paths in ModOrganizer:<br><br> Due to Somnium's non-standard folder structure, you need to manually update the binary paths in ModOrganizer:<br><br>

View File

@@ -1509,17 +1509,18 @@ class ModlistGalleryDialog(QDialog):
try: try:
# Remove all cards from layout # Remove all cards from layout
# CRITICAL FIX: Properly remove widgets to prevent overlapping and orphaned windows # CRITICAL FIX: Properly remove all widgets to prevent overlapping
# We need to explicitly remove widgets from the layout before taking items # Iterate backwards to avoid index shifting issues
# to ensure they're fully cleaned up, but we don't setParent(None) because for i in range(self.grid_layout.count() - 1, -1, -1):
# widgets are immediately re-added to the grid (Qt will reparent them). item = self.grid_layout.takeAt(i)
while self.grid_layout.count():
item = self.grid_layout.takeAt(0)
widget = item.widget() if item else None widget = item.widget() if item else None
if widget: if widget:
# Explicitly remove widget from layout to prevent overlapping # Hide widget during removal to prevent visual artifacts
self.grid_layout.removeWidget(widget) widget.hide()
del item del item
# Force layout update to ensure all widgets are removed
self.grid_layout.update()
# Calculate number of columns based on available width # Calculate number of columns based on available width
# Get the scroll area width (accounting for filter panel ~280px + margins) # Get the scroll area width (accounting for filter panel ~280px + margins)
@@ -1558,16 +1559,20 @@ class ModlistGalleryDialog(QDialog):
card = self.all_cards.get(modlist.machineURL) card = self.all_cards.get(modlist.machineURL)
if card: if card:
# Ensure widget is not already in the layout (prevent overlapping) # Safety check: ensure widget is not already in the layout
# If it is, remove it first (shouldn't happen after takeAt, but safety check) # (shouldn't happen after proper removal above, but defensive programming)
if card.parent() == self.grid_widget: already_in_layout = False
# Widget is already a child of grid_widget, check if it's in layout for i in range(self.grid_layout.count()):
for i in range(self.grid_layout.count()): item = self.grid_layout.itemAt(i)
item = self.grid_layout.itemAt(i) if item and item.widget() == card:
if item and item.widget() == card: # Widget is already in layout - this shouldn't happen, but handle it
# Already in layout, remove it first already_in_layout = True
self.grid_layout.removeWidget(card) self.grid_layout.removeWidget(card)
break break
# Ensure widget is visible and add to grid
if not already_in_layout or card.isHidden():
card.show()
self.grid_layout.addWidget(card, row, col) self.grid_layout.addWidget(card, row, col)
# Set column stretch - don't stretch card columns, but add a spacer column # Set column stretch - don't stretch card columns, but add a spacer column