diff --git a/linedance-api/app/routers/sync.py b/linedance-api/app/routers/sync.py index 0d4637df..fdecb495 100644 --- a/linedance-api/app/routers/sync.py +++ b/linedance-api/app/routers/sync.py @@ -53,6 +53,8 @@ class SongAltDanceData(BaseModel): class PlaylistSongData(BaseModel): song_local_id: str + song_title: str = "" + song_artist: str = "" position: int status: str = "pending" is_workshop: bool = False @@ -182,7 +184,15 @@ def push( playlist_id_map[pl.local_id] = project.id for ps in pl.songs: + # Prøv først via song_id_map (lokal ID) song_id = song_id_map.get(ps.song_local_id) + # Fallback: match på titel+artist + if not song_id and ps.song_title: + existing_song = db.query(Song).filter_by( + title=ps.song_title, artist=ps.song_artist + ).first() + if existing_song: + song_id = existing_song.id if not song_id: continue proj_song = ProjectSong( diff --git a/linedance-app/local/sync_manager.py b/linedance-app/local/sync_manager.py index 73e277f1..ad7cd50e 100644 --- a/linedance-app/local/sync_manager.py +++ b/linedance-app/local/sync_manager.py @@ -189,11 +189,16 @@ class SyncManager: ).fetchall(): pl_songs = [] for ps in conn.execute(""" - SELECT song_id, position, status, is_workshop, dance_override - FROM playlist_songs WHERE playlist_id=? ORDER BY position + SELECT s.id, s.title, s.artist, + ps.position, ps.status, ps.is_workshop, ps.dance_override + FROM playlist_songs ps + JOIN songs s ON s.id = ps.song_id + WHERE ps.playlist_id=? ORDER BY ps.position """, (pl["id"],)).fetchall(): pl_songs.append({ - "song_local_id": ps["song_id"] or "", + "song_local_id": str(ps["id"]), + "song_title": ps["title"] or "", + "song_artist": ps["artist"] or "", "position": int(ps["position"] or 1), "status": ps["status"] or "pending", "is_workshop": bool(ps["is_workshop"]), diff --git a/linedance-app/main.py b/linedance-app/main.py index bca49377..808c78d4 100644 --- a/linedance-app/main.py +++ b/linedance-app/main.py @@ -25,8 +25,12 @@ def main(): if _sys.platform == "win32": from PyQt6.QtCore import qInstallMessageHandler, QtMsgType def _qt_msg_handler(msg_type, context, message): - if "registerTimer" in message or "Unhandled scheme" in message: - return # ignorer + if any(x in message for x in [ + "registerTimer", "Unhandled scheme", + "Point size <= 0", "setPointSize", + "QFont::", + ]): + return print(message) qInstallMessageHandler(_qt_msg_handler) diff --git a/linedance-app/ui/main_window.py b/linedance-app/ui/main_window.py index e7a8f74f..f0e46828 100644 --- a/linedance-app/ui/main_window.py +++ b/linedance-app/ui/main_window.py @@ -466,8 +466,8 @@ class MainWindow(QMainWindow): SELECT s.id, s.title, s.artist, s.album, s.bpm, s.duration_sec, s.local_path, s.file_format, s.file_missing, - GROUP_CONCAT(DISTINCT d.name) AS dance_names, - GROUP_CONCAT(DISTINCT COALESCE(dl.name,'')) AS dance_levels, + GROUP_CONCAT(d.name, ',') AS dance_names, + GROUP_CONCAT(COALESCE(dl.name,''), ',') AS dance_levels, GROUP_CONCAT(DISTINCT ad.name) AS alt_dance_names FROM songs s LEFT JOIN song_dances sd ON sd.song_id = s.id diff --git a/linedance-app/ui/playlist_info_dialog.py b/linedance-app/ui/playlist_info_dialog.py index 51626782..db957189 100644 --- a/linedance-app/ui/playlist_info_dialog.py +++ b/linedance-app/ui/playlist_info_dialog.py @@ -41,7 +41,10 @@ class PlaylistInfoWindow(QWidget): playlist_panel.playlist_changed.connect(self._update) playlist_panel.status_changed.connect(lambda *_: self._update()) - def _build_ui(self): + def moveEvent(self, event): + from PyQt6.QtCore import QSettings + QSettings("LineDance", "Player").setValue("window/info_pos", self.pos()) + super().moveEvent(event) layout = QVBoxLayout(self) layout.setContentsMargins(12, 12, 12, 12) layout.setSpacing(8) diff --git a/linedance-app/ui/playlist_panel.py b/linedance-app/ui/playlist_panel.py index 30e197bb..5ef6e31e 100644 --- a/linedance-app/ui/playlist_panel.py +++ b/linedance-app/ui/playlist_panel.py @@ -668,12 +668,26 @@ class PlaylistPanel(QWidget): from ui.playlist_info_dialog import PlaylistInfoWindow from PyQt6.QtWidgets import QApplication + from PyQt6.QtCore import QSettings main = self.window() self._info_window = PlaylistInfoWindow(self, parent=main) QApplication.instance().aboutToQuit.connect(self._info_window.close) - if main: + + # Gendan gemt position eller placer ved siden af hovedvindue + s = QSettings("LineDance", "Player") + pos = s.value("window/info_pos") + if pos: + self._info_window.move(pos) + elif main: geo = main.geometry() - self._info_window.move(geo.right() + 10, geo.top() + 100) + self._info_window.move(geo.right() + 10, geo.top()) + + # Sikr at vinduet er på skærmen + screen = QApplication.primaryScreen().availableGeometry() + w_geo = self._info_window.frameGeometry() + x = max(0, min(w_geo.x(), screen.right() - w_geo.width())) + y = max(0, min(w_geo.y(), screen.bottom() - w_geo.height())) + self._info_window.move(x, y) self._info_window.show() def _change_dance(self, idx: int, song: dict): diff --git a/linedance-app/ui/tag_editor.py b/linedance-app/ui/tag_editor.py index 2bc87392..6fcd0c03 100644 --- a/linedance-app/ui/tag_editor.py +++ b/linedance-app/ui/tag_editor.py @@ -437,9 +437,14 @@ class TagEditorDialog(QDialog): # Skriv danse-navne til filen if local_path and can_write_dances(local_path): dance_names = [d["name"] for d in dances] - if not write_dances(local_path, dance_names): + try: + if not write_dances(local_path, dance_names): + QMessageBox.warning(self, "Advarsel", + "Gemt i database, men kunne ikke skrive til mp3-filen.\n" + "(Filen understøtter ikke dans-tags)") + except Exception as write_err: QMessageBox.warning(self, "Advarsel", - "Gemt i database, men kunne ikke skrive til filen.") + f"Gemt i database, men fejl ved skrivning til fil:\n{write_err}") self.accept()