From a930cbd7050a0f148c70c301edf256d8e6e9b0d6 Mon Sep 17 00:00:00 2001
From: Boris Yumankulov <boria138@altlinux.org>
Date: Tue, 3 Jun 2025 14:26:25 +0500
Subject: [PATCH] feat(ui): add ProtonDB, Steam, and WeAntiCheatYet badges to
 game detail page

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
---
 portprotonqt/game_card.py   | 18 +++++---
 portprotonqt/main_window.py | 89 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 99 insertions(+), 8 deletions(-)

diff --git a/portprotonqt/game_card.py b/portprotonqt/game_card.py
index 152474f..d484a00 100644
--- a/portprotonqt/game_card.py
+++ b/portprotonqt/game_card.py
@@ -217,7 +217,8 @@ class GameCard(QFrame):
         if self.context_menu_manager:
             self.context_menu_manager.show_context_menu(self, pos)
 
-    def getAntiCheatText(self, status):
+    @staticmethod
+    def getAntiCheatText(status: str) -> str:
             if not status:
                 return ""
             translations = {
@@ -229,7 +230,8 @@ class GameCard(QFrame):
             }
             return translations.get(status.lower(), "")
 
-    def getAntiCheatIconFilename(self, status):
+    @staticmethod
+    def getAntiCheatIconFilename(status: str) -> str:
         status = status.lower()
         if status in ("supported", "running"):
             return "platinum-gold"
@@ -237,7 +239,8 @@ class GameCard(QFrame):
             return "broken"
         return ""
 
-    def getProtonDBText(self, tier):
+    @staticmethod
+    def getProtonDBText(tier: str) -> str:
         if not tier:
             return ""
         translations = {
@@ -250,7 +253,8 @@ class GameCard(QFrame):
         }
         return translations.get(tier.lower(), "")
 
-    def getProtonDBIconFilename(self, tier):
+    @staticmethod
+    def getProtonDBIconFilename(tier: str) -> str:
         tier = tier.lower()
         if tier in ("platinum", "gold"):
             return "platinum-gold"
@@ -451,7 +455,8 @@ class GameCard(QFrame):
                 self.last_launch,
                 self.formatted_playtime,
                 self.protondb_tier,
-                self.steam_game
+                self.steam_game,
+                self.anticheat_status
             )
         super().mousePressEvent(event)
 
@@ -467,7 +472,8 @@ class GameCard(QFrame):
                 self.last_launch,
                 self.formatted_playtime,
                 self.protondb_tier,
-                self.steam_game
+                self.steam_game,
+                self.anticheat_status
             )
         else:
             super().keyPressEvent(event)
diff --git a/portprotonqt/main_window.py b/portprotonqt/main_window.py
index 943d489..c326adf 100644
--- a/portprotonqt/main_window.py
+++ b/portprotonqt/main_window.py
@@ -1320,7 +1320,7 @@ class MainWindow(QMainWindow):
     def darkenColor(self, color, factor=200):
         return color.darker(factor)
 
-    def openGameDetailPage(self, name, description, cover_path=None, appid="", exec_line="", controller_support="", last_launch="", formatted_playtime="", protondb_tier="", steam_game=""):
+    def openGameDetailPage(self, name, description, cover_path=None, appid="", exec_line="", controller_support="", last_launch="", formatted_playtime="", protondb_tier="", steam_game="", anticheat_status=""):
         detailPage = QWidget()
         self._animations = {}
         imageLabel = QLabel()
@@ -1375,7 +1375,7 @@ class MainWindow(QMainWindow):
 
         coverLayout.addWidget(imageLabel)
 
-        # Добавляем значок избранного поверх обложки в левом верхнем углу
+        # Значок избранного
         favoriteLabelCover = ClickableLabel(coverFrame)
         favoriteLabelCover.setFixedSize(*self.theme.favoriteLabelSize)
         favoriteLabelCover.setStyleSheet(self.theme.FAVORITE_LABEL_STYLE)
@@ -1388,6 +1388,91 @@ class MainWindow(QMainWindow):
         favoriteLabelCover.move(8, 8)
         favoriteLabelCover.raise_()
 
+        # Добавляем бейджи (ProtonDB, Steam, WeAntiCheatYet)
+        right_margin = 8
+        badge_spacing = 5
+        top_y = 10
+        badge_y_positions = []
+        badge_width = int(300 * 2/3)  # 2/3 ширины обложки (300 px)
+
+        # ProtonDB бейдж
+        protondb_text = GameCard.getProtonDBText(protondb_tier)
+        if protondb_text:
+            icon_filename = GameCard.getProtonDBIconFilename(protondb_tier)
+            icon = self.theme_manager.get_icon(icon_filename, self.current_theme_name)
+            protondbLabel = ClickableLabel(
+                protondb_text,
+                icon=icon,
+                parent=coverFrame,
+                icon_size=16,
+                icon_space=3,
+            )
+            protondbLabel.setStyleSheet(self.theme.get_protondb_badge_style(protondb_tier))
+            protondbLabel.setFixedWidth(badge_width)
+            protondbLabel.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(f"https://www.protondb.com/app/{appid}")))
+            protondb_visible = True
+        else:
+            protondbLabel = ClickableLabel("", parent=coverFrame, icon_size=16, icon_space=3)
+            protondbLabel.setFixedWidth(badge_width)
+            protondbLabel.setVisible(False)
+            protondb_visible = False
+
+        # Steam бейдж
+        steam_icon = self.theme_manager.get_icon("steam")
+        steamLabel = ClickableLabel(
+            "Steam",
+            icon=steam_icon,
+            parent=coverFrame,
+            icon_size=16,
+            icon_space=5,
+        )
+        steamLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE)
+        steamLabel.setFixedWidth(badge_width)
+        steam_visible = (str(steam_game).lower() == "true")
+        steamLabel.setVisible(steam_visible)
+        steamLabel.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(f"https://steamcommunity.com/app/{appid}")))
+
+        # WeAntiCheatYet бейдж
+        anticheat_text = GameCard.getAntiCheatText(anticheat_status)
+        if anticheat_text:
+            icon_filename = GameCard.getAntiCheatIconFilename(anticheat_status)
+            icon = self.theme_manager.get_icon(icon_filename, self.current_theme_name)
+            anticheatLabel = ClickableLabel(
+                anticheat_text,
+                icon=icon,
+                parent=coverFrame,
+                icon_size=16,
+                icon_space=3,
+            )
+            anticheatLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE)
+            anticheatLabel.setFixedWidth(badge_width)
+            anticheatLabel.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(f"https://areweanticheatyet.com/game/{name.lower().replace(' ', '-')}")))
+            anticheat_visible = True
+        else:
+            anticheatLabel = ClickableLabel("", parent=coverFrame, icon_size=16, icon_space=3)
+            anticheatLabel.setFixedWidth(badge_width)
+            anticheatLabel.setVisible(False)
+            anticheat_visible = False
+
+        # Расположение бейджей
+        if steam_visible:
+            steam_x = 300 - badge_width - right_margin
+            steamLabel.move(steam_x, top_y)
+            badge_y_positions.append(top_y + steamLabel.height())
+        if protondb_visible:
+            protondb_x = 300 - badge_width - right_margin
+            protondb_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
+            protondbLabel.move(protondb_x, protondb_y)
+            badge_y_positions.append(protondb_y + protondbLabel.height())
+        if anticheat_visible:
+            anticheat_x = 300 - badge_width - right_margin
+            anticheat_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
+            anticheatLabel.move(anticheat_x, anticheat_y)
+
+        anticheatLabel.raise_()
+        protondbLabel.raise_()
+        steamLabel.raise_()
+
         contentFrameLayout.addWidget(coverFrame)
 
         # Детали игры (справа)