88from PyQt6 .QtWidgets import (
99 QDialog , QVBoxLayout , QGroupBox , QTreeWidget , QTreeWidgetItem , QPushButton ,
1010 QHBoxLayout , QFileDialog , QStyle , QMessageBox , QLabel , QProgressBar , QTextEdit ,
11- QFrame
11+ QFrame , QCheckBox
1212)
1313from PyQt6 .QtCore import Qt , QTimer , pyqtSignal , QThread
1414from PyQt6 .QtGui import QTextCursor , QIcon
@@ -91,8 +91,17 @@ def setup_ui(self):
9191 self .ffmpeg_btn = QPushButton (tr ('settings.ffmpeg_checking' ))
9292 self .ffmpeg_btn .clicked .connect (self .update_ffmpeg )
9393 deps_layout .addWidget (self .ffmpeg_btn )
94+
95+ self .app_update_btn = QPushButton (tr ('updater.checking' ))
96+ self .app_update_btn .clicked .connect (self .update_app )
97+ deps_layout .addWidget (self .app_update_btn )
9498
9599 deps_layout .addStretch ()
100+
101+ self .auto_update_chk = QCheckBox (tr ('updater.check_updates_auto' ))
102+ self .auto_update_chk .setChecked (True )
103+ deps_layout .addWidget (self .auto_update_chk )
104+
96105 deps_group .setLayout (deps_layout )
97106
98107 storage_group = QGroupBox (tr ('settings.storage_group' ))
@@ -117,6 +126,7 @@ def setup_ui(self):
117126
118127 QTimer .singleShot (100 , self .check_libmpv_version )
119128 QTimer .singleShot (200 , self .check_ffmpeg_version )
129+ QTimer .singleShot (300 , self .check_app_version )
120130
121131 save_btn = QPushButton (tr ('settings.save' ))
122132 save_btn .setIcon (self .icons .get ('save' , QIcon ()))
@@ -243,6 +253,8 @@ def load_current_settings(self):
243253 self .pathslist .addTopLevelItem (item )
244254 self ._validate_path (item )
245255
256+ self .auto_update_chk .setChecked (self .config .get_check_updates_on_start ())
257+
246258 def _validate_path (self , item ):
247259 path = item .text (0 )
248260 if os .path .exists (path ):
@@ -266,6 +278,7 @@ def save_settings(self):
266278
267279 self .config .set_library_paths (paths )
268280 self .config .set_excluded_library_paths (excluded_paths )
281+ self .config .set_check_updates_on_start (self .auto_update_chk .isChecked ())
269282
270283 self .accept ()
271284
@@ -406,3 +419,34 @@ def do_update():
406419 dialog .exec ()
407420
408421 self .check_ffmpeg_version ()
422+
423+ def check_app_version (self ):
424+ """Check if a newer app version is available on GitHub."""
425+ try :
426+ from update_app import get_current_version , get_latest_release , compare_versions
427+ current = get_current_version ()
428+ release = get_latest_release ()
429+
430+ if release :
431+ latest = release ['tag' ].lstrip ('v' )
432+ if compare_versions (current , latest ):
433+ self .app_update_btn .setText (f" SP Video Courses Player ({ current } → { latest } )" )
434+ self .app_update_btn .setIcon (self .icons .get ('upload' , QIcon ()))
435+ self .app_update_btn .setToolTip (tr ('updater.available' , version = latest ))
436+ else :
437+ self .app_update_btn .setText (f" SP Video Courses Player ({ current } )" )
438+ self .app_update_btn .setIcon (self .icons .get ('check' , QIcon ()))
439+ self .app_update_btn .setToolTip (tr ('updater.no_updates' , version = current ))
440+ else :
441+ self .app_update_btn .setText (f" SP Video Courses Player ({ current } )" )
442+ self .app_update_btn .setIcon (self .icons .get ('check' , QIcon ()))
443+ self .app_update_btn .setToolTip (tr ('updater.no_updates' , version = current ))
444+ except Exception as e :
445+ self .app_update_btn .setText (" SP Video Courses Player" )
446+ self .app_update_btn .setIcon (self .icons .get ('fail' , QIcon ()))
447+ self .app_update_btn .setToolTip (str (e ))
448+
449+ def update_app (self ):
450+ """Trigger app update via parent window."""
451+ if self .parent () and hasattr (self .parent (), '_check_for_update' ):
452+ self .parent ()._check_for_update (force = True )
0 commit comments