From 49a03a551dd24cc7eb1850baf726056a48ea0447 Mon Sep 17 00:00:00 2001
From: loathingKernel <142770+loathingKernel@users.noreply.github.com>
Date: Sat, 23 Sep 2023 20:24:28 +0300
Subject: [PATCH] Store WIP
---
rare/components/tabs/store/__init__.py | 17 +-
rare/components/tabs/store/__main__.py | 2 +-
rare/components/tabs/store/api/debug.py | 2 +-
.../tabs/store/api/graphql/schema.graphql | 35 ++
.../components/tabs/store/api/models/query.py | 4 +-
.../tabs/store/api/models/response.py | 176 +-------
rare/components/tabs/store/game_info.py | 11 +-
rare/components/tabs/store/game_widgets.py | 3 +-
rare/components/tabs/store/image_widget.py | 53 +--
rare/components/tabs/store/search_results.py | 18 +-
rare/components/tabs/store/shop_api_core.py | 38 +-
rare/components/tabs/store/shop_widget.py | 200 +++++----
rare/components/tabs/store/wishlist.py | 6 +-
rare/ui/components/tabs/store/store.py | 65 +--
rare/ui/components/tabs/store/store.ui | 393 +++++++-----------
rare/utils/qt_requests.py | 4 +-
16 files changed, 376 insertions(+), 651 deletions(-)
diff --git a/rare/components/tabs/store/__init__.py b/rare/components/tabs/store/__init__.py
index 811fbe14c..a0ed5ebcf 100644
--- a/rare/components/tabs/store/__init__.py
+++ b/rare/components/tabs/store/__init__.py
@@ -1,12 +1,11 @@
from legendary.core import LegendaryCore
-from rare.shared import RareCore
from rare.utils.paths import cache_dir
from rare.widgets.side_tab import SideTabWidget
+from .api.models.response import CatalogOfferModel
from .game_info import ShopGameInfo
from .search_results import SearchResults
from .shop_api_core import ShopApiCore
-from .api.models.response import CatalogOfferModel
from .shop_widget import ShopWidget
from .wishlist import WishlistWidget, Wishlist
@@ -28,11 +27,11 @@ def __init__(self, core: LegendaryCore, parent=None):
self.shop = ShopWidget(cache_dir(), self.core, self.api_core, parent=self)
self.shop_index = self.addTab(self.shop, self.tr("Store"))
self.shop.show_game.connect(self.show_game)
- self.shop.show_info.connect(self.show_search)
+ # self.shop.show_info.connect(self.show_search)
- self.search = SearchResults(self.api_core, parent=self)
- self.search_index = self.addTab(self.search, self.tr("Search"), self.tr("Results"))
- self.search.show_info.connect(self.show_game)
+ # self.search = SearchResults(self.api_core, parent=self)
+ # self.search_index = self.addTab(self.search, self.tr("Search"), self.tr("Results"))
+ # self.search.show_info.connect(self.show_game)
# self.search.back_button.clicked.connect(lambda: self.setCurrentIndex(self.shop_index))
self.info = ShopGameInfo(
@@ -67,6 +66,6 @@ def show_game(self, data: CatalogOfferModel):
self.info.update_game(data)
self.setCurrentIndex(self.info_index)
- def show_search(self, text: str):
- self.search.load_results(text)
- self.setCurrentIndex(self.search_index)
+ # def show_search(self, text: str):
+ # self.search.load_results(text)
+ # self.setCurrentIndex(self.search_index)
diff --git a/rare/components/tabs/store/__main__.py b/rare/components/tabs/store/__main__.py
index a7366a13c..b4936fd10 100644
--- a/rare/components/tabs/store/__main__.py
+++ b/rare/components/tabs/store/__main__.py
@@ -22,9 +22,9 @@ def __init__(self):
if __name__ == "__main__":
- from rare.utils.misc import set_style_sheet
import rare.resources.static_css
import rare.resources.stylesheets.RareStyle
+ from rare.utils.misc import set_style_sheet
app = QApplication(sys.argv)
app.setApplicationName("Rare")
diff --git a/rare/components/tabs/store/api/debug.py b/rare/components/tabs/store/api/debug.py
index 083fcca27..24a20016a 100644
--- a/rare/components/tabs/store/api/debug.py
+++ b/rare/components/tabs/store/api/debug.py
@@ -1,7 +1,7 @@
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTreeView, QDialog, QVBoxLayout
-from utils.json_formatter import QJsonModel
+from rare.utils.json_formatter import QJsonModel
class DebugView(QTreeView):
diff --git a/rare/components/tabs/store/api/graphql/schema.graphql b/rare/components/tabs/store/api/graphql/schema.graphql
index 6f3edfdad..676fcfe55 100644
--- a/rare/components/tabs/store/api/graphql/schema.graphql
+++ b/rare/components/tabs/store/api/graphql/schema.graphql
@@ -38,4 +38,39 @@ type LineOfferRes {
type GetPriceRes {
totalPrice: TotalPrice
lineOffers: [LineOfferRes]
+}
+
+type Image {
+ type: String
+ url: String
+ alt: String
+}
+
+type StorePageMapping {
+ cmsSlug: String
+ offerId: ID
+ prePurchaseOfferId: ID
+}
+
+type PageSandboxModel {
+ pageSlug: String
+ pageType: String
+ productId: ID
+ sandboxId: ID
+ createdDate: Date
+ updatedDate: Date
+ deletedDate: Date
+ mappings: [StorePageMapping]
+}
+
+type CatalogNamespace {
+ parent: ID
+ displayName: String
+ store: String
+ mappings: [PageSandboxModel]
+}
+
+type CatalogItem {
+ id: ID
+ namespace: ID
}
\ No newline at end of file
diff --git a/rare/components/tabs/store/api/models/query.py b/rare/components/tabs/store/api/models/query.py
index 925cc5005..f3f21ca85 100644
--- a/rare/components/tabs/store/api/models/query.py
+++ b/rare/components/tabs/store/api/models/query.py
@@ -6,11 +6,11 @@
@dataclass
class SearchDateRange:
start_date: datetime = datetime(year=1990, month=1, day=1, tzinfo=timezone.utc)
- end_date: datetime = datetime.utcnow()
+ end_date: datetime = datetime.utcnow().replace(tzinfo=timezone.utc)
def __str__(self):
def fmt_date(date: datetime) -> str:
- # lk: The formatting accepted by the GraphQL API is either '%Y-%m-%dT%H:%M:%S.000Z' or '%Y-%m-%dT'
+ # lk: The formatting accepted by the GraphQL API is either '%Y-%m-%dT%H:%M:%S.000Z' or '%Y-%m-%d'
return datetime.strftime(date, '%Y-%m-%dT%H:%M:%S.000Z')
return f"[{fmt_date(self.start_date)},{fmt_date(self.end_date)}]"
diff --git a/rare/components/tabs/store/api/models/response.py b/rare/components/tabs/store/api/models/response.py
index 182985a16..6a7672f24 100644
--- a/rare/components/tabs/store/api/models/response.py
+++ b/rare/components/tabs/store/api/models/response.py
@@ -1,8 +1,10 @@
import logging
from dataclasses import dataclass, field
-from datetime import datetime, timezone
+from datetime import datetime
from typing import List, Dict, Any, Type, Optional
+from .utils import parse_date
+
logger = logging.getLogger("StoreApiModels")
# lk: Typing overloads for unimplemented types
@@ -13,171 +15,11 @@
CustomAttributeModel = Dict
ItemModel = Dict
SellerModel = Dict
-OfferMappingModel = Dict
+PageSandboxModel = Dict
TagModel = Dict
PromotionsModel = Dict
-def parse_date(date: str):
- return datetime.fromisoformat(date[:-1]).replace(tzinfo=timezone.utc)
-
-
-@dataclass
-class DieselSystemDetailItem:
- p_type: Optional[str] = None
- minimum: Optional[str] = None
- recommended: Optional[str] = None
- title: Optional[str] = None
- unmapped: Dict[str, Any] = field(default_factory=dict)
-
- @classmethod
- def from_dict(cls: Type["DieselSystemDetailItem"], src: Dict[str, Any]) -> "DieselSystemDetailItem":
- d = src.copy()
- tmp = cls(
- p_type=d.pop("_type", ""),
- minimum=d.pop("minimum", ""),
- recommended=d.pop("recommended", ""),
- title=d.pop("title", ""),
- )
- tmp.unmapped = d
- return tmp
-
-
-@dataclass
-class DieselSystemDetail:
- p_type: Optional[str] = None
- details: Optional[List[DieselSystemDetailItem]] = None
- system_type: Optional[str] = None
- unmapped: Dict[str, Any] = field(default_factory=dict)
-
- @classmethod
- def from_dict(cls: Type["DieselSystemDetail"], src: Dict[str, Any]) -> "DieselSystemDetail":
- d = src.copy()
- _details = d.pop("details", [])
- details = [] if _details else None
- for item in _details:
- detail = DieselSystemDetailItem.from_dict(item)
- details.append(detail)
- tmp = cls(
- p_type=d.pop("_type", ""),
- details=details,
- system_type=d.pop("systemType", ""),
- )
- tmp.unmapped = d
- return tmp
-
-
-@dataclass
-class DieselSystemDetails:
- p_type: Optional[str] = None
- languages: Optional[List[str]] = None
- rating: Optional[Dict] = None
- systems: Optional[List[DieselSystemDetail]] = None
- unmapped: Dict[str, Any] = field(default_factory=dict)
-
- @classmethod
- def from_dict(cls: Type["DieselSystemDetails"], src: Dict[str, Any]) -> "DieselSystemDetails":
- d = src.copy()
- _systems = d.pop("systems", [])
- systems = [] if _systems else None
- for item in _systems:
- system = DieselSystemDetail.from_dict(item)
- systems.append(system)
- tmp = cls(
- p_type=d.pop("_type", ""),
- languages=d.pop("languages", []),
- rating=d.pop("rating", {}),
- systems=systems,
- )
- tmp.unmapped = d
- return tmp
-
-
-@dataclass
-class DieselProductAbout:
- p_type: Optional[str] = None
- desciption: Optional[str] = None
- developer_attribution: Optional[str] = None
- publisher_attribution: Optional[str] = None
- short_description: Optional[str] = None
- unmapped: Dict[str, Any] = field(default_factory=dict)
-
- @classmethod
- def from_dict(cls: Type["DieselProductAbout"], src: Dict[str, Any]) -> "DieselProductAbout":
- d = src.copy()
- tmp = cls(
- p_type=d.pop("_type", ""),
- desciption=d.pop("description", ""),
- developer_attribution=d.pop("developerAttribution", ""),
- publisher_attribution=d.pop("publisherAttribution", ""),
- short_description=d.pop("shortDescription", ""),
- )
- tmp.unmapped = d
- return tmp
-
-
-@dataclass
-class DieselProductDetail:
- p_type: Optional[str] = None
- about: Optional[DieselProductAbout] = None
- requirements: Optional[DieselSystemDetails] = None
- social_links: Optional[DieselSocialLinks] = None
- unmapped: Dict[str, Any] = field(default_factory=dict)
-
- @classmethod
- def from_dict(cls: Type["DieselProductDetail"], src: Dict[str, Any]) -> "DieselProductDetail":
- d = src.copy()
- about = DieselProductAbout.from_dict(x) if (x := d.pop("about"), {}) else None
- requirements = DieselSystemDetails.from_dict(x) if (x := d.pop("requirements", {})) else None
- tmp = cls(
- p_type=d.pop("_type", ""),
- about=about,
- requirements=requirements,
- social_links=d.pop("socialLinks", {}),
- )
- tmp.unmapped = d
- return tmp
-
-
-@dataclass
-class DieselProduct:
- p_id: Optional[str] = None
- p_images_: Optional[List[str]] = None
- p_locale: Optional[str] = None
- p_slug: Optional[str] = None
- p_title: Optional[str] = None
- p_url_pattern: Optional[str] = None
- namespace: Optional[str] = None
- pages: Optional[List["DieselProduct"]] = None
- data: Optional[DieselProductDetail] = None
- product_name: Optional[str] = None
- unmapped: Dict[str, Any] = field(default_factory=dict)
-
- @classmethod
- def from_dict(cls: Type["DieselProduct"], src: Dict[str, Any]) -> "DieselProduct":
- d = src.copy()
- _pages = d.pop("pages", [])
- pages = [] if _pages else None
- for item in _pages:
- page = DieselProduct.from_dict(item)
- pages.append(page)
- data = DieselProductDetail.from_dict(x) if (x := d.pop("data", {})) else None
- tmp = cls(
- p_id=d.pop("_id", ""),
- p_images_=d.pop("_images_", []),
- p_locale=d.pop("_locale", ""),
- p_slug=d.pop("_slug", ""),
- p_title=d.pop("_title", ""),
- p_url_pattern=d.pop("_urlPattern", ""),
- namespace=d.pop("namespace", ""),
- pages=pages,
- data=data,
- product_name=d.pop("productName", ""),
- )
- tmp.unmapped = d
- return tmp
-
-
@dataclass
class ImageUrlModel:
type: Optional[str] = None
@@ -271,14 +113,14 @@ def for_dimensions(self, w: int, h: int) -> ImageUrlModel:
@dataclass
-class PriceModel:
+class GetPriceResModel:
total_price: Optional[TotalPriceModel] = None
fmt_price: Optional[FmtPriceModel] = None
line_offers: Optional[LineOffersModel] = None
unmapped: Dict[str, Any] = field(default_factory=dict)
@classmethod
- def from_dict(cls: Type["PriceModel"], src: Dict[str, Any]) -> "PriceModel":
+ def from_dict(cls: Type["GetPriceResModel"], src: Dict[str, Any]) -> "GetPriceResModel":
d = src.copy()
tmp = cls(
total_price=d.pop("totalPrice", {}),
@@ -302,9 +144,9 @@ class CatalogOfferModel:
items: Optional[List[ItemModel]] = None
key_images: Optional[KeyImagesModel] = None
namespace: Optional[str] = None
- offer_mappings: Optional[List[OfferMappingModel]] = None
+ offer_mappings: Optional[List[PageSandboxModel]] = None
offer_type: Optional[str] = None
- price: Optional[PriceModel] = None
+ price: Optional[GetPriceResModel] = None
product_slug: Optional[str] = None
promotions: Optional[PromotionsModel] = None
seller: Optional[SellerModel] = None
@@ -322,7 +164,7 @@ def from_dict(cls: Type["CatalogOfferModel"], src: Dict[str, Any]) -> "CatalogOf
effective_date = parse_date(x) if (x := d.pop("effectiveDate", "")) else None
expiry_date = parse_date(x) if (x := d.pop("expiryDate", "")) else None
key_images = KeyImagesModel.from_list(d.pop("keyImages", []))
- price = PriceModel.from_dict(x) if (x := d.pop("price", {})) else None
+ price = GetPriceResModel.from_dict(x) if (x := d.pop("price", {})) else None
viewable_date = parse_date(x) if (x := d.pop("viewableDate", "")) else None
tmp = cls(
catalog_ns=d.pop("catalogNs", {}),
diff --git a/rare/components/tabs/store/game_info.py b/rare/components/tabs/store/game_info.py
index 19a27524d..af591120f 100644
--- a/rare/components/tabs/store/game_info.py
+++ b/rare/components/tabs/store/game_info.py
@@ -1,5 +1,4 @@
import logging
-from pprint import pprint
from typing import List
from PyQt5.QtCore import Qt, QUrl
@@ -12,14 +11,14 @@
QSizePolicy,
)
-from rare.components.tabs.store.api.models.response import CatalogOfferModel, DieselProduct, DieselProductDetail
-from rare.shared import LegendaryCoreSingleton
-from rare.shared.image_manager import ImageSize
+from rare.models.image import ImageSize
from rare.ui.components.tabs.store.shop_game_info import Ui_ShopInfo
from rare.utils.misc import icon
-from rare.widgets.side_tab import SideTabWidget, SideTabContents
from rare.widgets.elide_label import ElideLabel
+from rare.widgets.side_tab import SideTabWidget, SideTabContents
from .api.debug import DebugDialog
+from .api.models.diesel import DieselProduct, DieselProductDetail
+from .api.models.response import CatalogOfferModel
from .image_widget import ShopImageWidget
logger = logging.getLogger("ShopInfo")
@@ -107,7 +106,7 @@ def update_game(self, offer: CatalogOfferModel):
# init API request
if slug:
- self.api_core.get_game(offer.product_slug, is_bundle, self.data_received)
+ self.api_core.get_game_config_cms(offer.product_slug, is_bundle, self.data_received)
# else:
# self.data_received({})
self.offer = offer
diff --git a/rare/components/tabs/store/game_widgets.py b/rare/components/tabs/store/game_widgets.py
index 92adbc6bb..b54882126 100644
--- a/rare/components/tabs/store/game_widgets.py
+++ b/rare/components/tabs/store/game_widgets.py
@@ -3,10 +3,9 @@
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QMouseEvent
from PyQt5.QtWidgets import QPushButton
-from orjson import orjson
from rare.components.tabs.store.api.models.response import CatalogOfferModel
-from rare.shared.image_manager import ImageSize
+from rare.models.image import ImageSize
from rare.utils.misc import icon
from rare.utils.qt_requests import QtRequestManager
from .api.debug import DebugDialog
diff --git a/rare/components/tabs/store/image_widget.py b/rare/components/tabs/store/image_widget.py
index ec9259438..5d02b4f44 100644
--- a/rare/components/tabs/store/image_widget.py
+++ b/rare/components/tabs/store/image_widget.py
@@ -1,10 +1,7 @@
-from PyQt5.QtCore import QEvent, QObject
from PyQt5.QtCore import Qt
from PyQt5.QtGui import (
QPixmap,
QImage,
- QMovie,
- QShowEvent,
)
from PyQt5.QtWidgets import (
QWidget,
@@ -17,51 +14,7 @@
from rare.utils.qt_requests import QtRequestManager
from rare.widgets.image_widget import ImageWidget
-
-
-class WaitingSpinner(QLabel):
- def __init__(self, autostart=False, parent=None):
- super(WaitingSpinner, self).__init__(parent=parent)
- self.setObjectName(type(self).__name__)
- self.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
- self.movie = QMovie(":/images/loader.gif", parent=self)
- self.setFixedSize(128, 128)
- self.setMovie(self.movie)
- if self.parent() is not None:
- self.parent().installEventFilter(self)
- if autostart:
- self.movie.start()
-
- def __center_on_parent(self):
- rect = self.rect()
- rect.moveCenter(self.parent().contentsRect().center())
- self.setGeometry(rect)
-
- def event(self, e: QEvent) -> bool:
- if e.type() == QEvent.ParentAboutToChange:
- if self.parent() is not None:
- self.parent().removeEventFilter(self)
- if e.type() == QEvent.ParentChange:
- if self.parent() is not None:
- self.parent().installEventFilter(self)
- return super().event(e)
-
- def showEvent(self, a0: QShowEvent) -> None:
- self.__center_on_parent()
-
- def eventFilter(self, a0: QObject, a1: QEvent) -> bool:
- if a0 is self.parent() and a1.type() == QEvent.Resize:
- self.__center_on_parent()
- return a0.event(a1)
- return False
-
- def start(self):
- self.setVisible(True)
- self.movie.start()
-
- def stop(self):
- self.setVisible(False)
- self.movie.stop()
+from rare.widgets.loading_widget import LoadingWidget
class IconWidget(object):
@@ -76,7 +29,7 @@ def setupUi(self, widget: QWidget):
# on-hover popup
self.mini_widget = QWidget(parent=widget)
self.mini_widget.setObjectName(f"{type(self).__name__}MiniWidget")
- self.mini_widget.setFixedHeight(widget.height() // 4)
+ self.mini_widget.setFixedHeight(int(widget.height() // 3))
# game title
self.title_label = QLabel(parent=self.mini_widget)
@@ -134,7 +87,7 @@ class ShopImageWidget(ImageWidget):
def __init__(self, manager: QtRequestManager, parent=None):
super(ShopImageWidget, self).__init__(parent=parent)
self.ui = IconWidget()
- self.spinner = WaitingSpinner(parent=self)
+ self.spinner = LoadingWidget(parent=self)
self.spinner.setVisible(False)
self.manager = manager
diff --git a/rare/components/tabs/store/search_results.py b/rare/components/tabs/store/search_results.py
index 24ec3fd1c..bbd434034 100644
--- a/rare/components/tabs/store/search_results.py
+++ b/rare/components/tabs/store/search_results.py
@@ -7,26 +7,24 @@
QLabel, QScrollArea,
)
-from rare.shared.image_manager import ImageSize
+from rare.models.image import ImageSize
from rare.utils.qt_requests import QtRequestManager
from rare.widgets.flow_layout import FlowLayout
from rare.widgets.side_tab import SideTabContents
-from .image_widget import ShopImageWidget
-
from .api.debug import DebugDialog
from .api.models.response import CatalogOfferModel
+from .image_widget import ShopImageWidget
-class SearchResults(QScrollArea, SideTabContents):
+class SearchResultsWidget(QScrollArea):
show_info = pyqtSignal(CatalogOfferModel)
def __init__(self, api_core, parent=None):
- super(SearchResults, self).__init__(parent=parent)
- self.implements_scrollarea = True
+ super(SearchResultsWidget, self).__init__(parent=parent)
self.api_core = api_core
self.results_container = QWidget(self)
- self.results_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ self.results_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.results_layout = FlowLayout(self.results_container)
self.setWidget(self.results_container)
self.setWidgetResizable(True)
@@ -61,6 +59,12 @@ def show_results(self, results: dict):
self.setEnabled(True)
+class SearchResults(SearchResultsWidget, SideTabContents):
+ def __init__(self, api_core, parent=None):
+ super(SearchResults, self).__init__(api_core, parent=parent)
+ self.implements_scrollarea = True
+
+
class SearchResultItem(ShopImageWidget):
show_info = pyqtSignal(CatalogOfferModel)
diff --git a/rare/components/tabs/store/shop_api_core.py b/rare/components/tabs/store/shop_api_core.py
index 0510d6920..4c018a8bf 100644
--- a/rare/components/tabs/store/shop_api_core.py
+++ b/rare/components/tabs/store/shop_api_core.py
@@ -14,8 +14,8 @@
from rare.utils.paths import cache_dir
from rare.utils.qt_requests import QtRequestManager
from .api.models.query import SearchStoreQuery
+from .api.models.diesel import DieselProduct
from .api.models.response import (
- DieselProduct,
ResponseModel,
CatalogOfferModel,
)
@@ -152,13 +152,13 @@ def browse_games(self, browse_model: SearchStoreQuery, handle_func):
"query": search_query,
"variables": browse_model.to_dict()
}
- debug = DebugDialog(payload["variables"], None)
- debug.exec()
+ # debug = DebugDialog(payload["variables"], None)
+ # debug.exec()
self.manager.post(graphql_url, lambda data: self.__handle_browse_games(data, handle_func), payload)
def __handle_browse_games(self, data, handle_func):
- debug = DebugDialog(data, None)
- debug.exec()
+ # debug = DebugDialog(data, None)
+ # debug.exec()
self.browse_active = False
if data is None:
data = {}
@@ -181,15 +181,29 @@ def __handle_browse_games(self, data, handle_func):
self.browse_games(*self.next_browse_request) # pylint: disable=E1120
self.next_browse_request = tuple(())
- def get_game(self, slug: str, is_bundle: bool, handle_func):
+ def get_game_config_graphql(self, namespace: str, handle_func):
+ payload = {
+ "query": config_query,
+ "variables": {
+ "namespace": namespace
+ }
+ }
+
+ def __make_graphql_query(self):
+ pass
+
+ def __make_api_query(self):
+ pass
+
+ def get_game_config_cms(self, slug: str, is_bundle: bool, handle_func):
url = "https://store-content.ak.epicgames.com/api"
url += f"/{self.locale}/content/{'products' if not is_bundle else 'bundles'}/{slug}"
self.manager.get(url, lambda data: self.__handle_get_game(data, handle_func))
@staticmethod
def __handle_get_game(data, handle_func):
- debug = DebugDialog(data, None)
- debug.exec()
+ # debug = DebugDialog(data, None)
+ # debug.exec()
try:
product = DieselProduct.from_dict(data)
handle_func(product)
@@ -213,8 +227,8 @@ def add_to_wishlist(self, namespace, offer_id, handle_func: callable):
self.authed_manager.post(graphql_url, lambda data: self._handle_add_to_wishlist(data, handle_func), payload)
def _handle_add_to_wishlist(self, data, handle_func):
- debug = DebugDialog(data, None)
- debug.exec()
+ # debug = DebugDialog(data, None)
+ # debug.exec()
try:
response = ResponseModel.from_dict(data)
data = response.data.wishlist.add_to_wishlist
@@ -239,8 +253,8 @@ def remove_from_wishlist(self, namespace, offer_id, handle_func: callable):
payload)
def _handle_remove_from_wishlist(self, data, handle_func):
- debug = DebugDialog(data, None)
- debug.exec()
+ # debug = DebugDialog(data, None)
+ # debug.exec()
try:
response = ResponseModel.from_dict(data)
data = response.data.wishlist.remove_from_wishlist
diff --git a/rare/components/tabs/store/shop_widget.py b/rare/components/tabs/store/shop_widget.py
index 3489f9bb2..4f61a7f51 100644
--- a/rare/components/tabs/store/shop_widget.py
+++ b/rare/components/tabs/store/shop_widget.py
@@ -7,9 +7,8 @@
QGroupBox,
QCheckBox,
QLabel,
- QPushButton,
QHBoxLayout,
- QWidget, QSizePolicy, QStackedLayout,
+ QWidget, QSizePolicy, QScrollArea, QVBoxLayout, QFrame, QSpacerItem,
)
from legendary.core import LegendaryCore
@@ -17,15 +16,16 @@
from rare.utils.extra_widgets import ButtonLineEdit
from rare.widgets.flow_layout import FlowLayout
from rare.widgets.side_tab import SideTabContents
+from rare.widgets.sliding_stack import SlidingStackedWidget
+from .store_widgets import ShopGroupBox
from .api.models.query import SearchStoreQuery
from .api.models.response import CatalogOfferModel, WishlistItemModel
+from .api.models.utils import parse_date
from .constants import Constants
from .game_widgets import GameWidget
-from .image_widget import WaitingSpinner
+from .search_results import SearchResults
from .shop_api_core import ShopApiCore
-from .api.models.utils import parse_date
-
logger = logging.getLogger("Shop")
@@ -47,39 +47,56 @@ def __init__(self, cache_dir, core: LegendaryCore, shop_api: ShopApiCore, parent
self.types = []
self.update_games_allowed = True
- self.ui.free_scrollarea.setDisabled(True)
-
self.free_game_widgets = []
self.active_search_request = False
self.next_search = ""
self.wishlist: List = []
- self.discounts_layout = QStackedLayout(self.ui.discounts_group)
- self.discounts_spinner = WaitingSpinner(self.ui.discounts_group)
- self.discounts_flow = QWidget(self.ui.discounts_group)
- self.discounts_flow.setLayout(FlowLayout(self.discounts_flow))
- self.discounts_flow.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.discounts_layout.addWidget(self.discounts_spinner)
- self.discounts_layout.addWidget(self.discounts_flow)
-
- self.discounts_spinner.start()
- self.discounts_layout.setCurrentWidget(self.discounts_spinner)
-
- self.games_layout = QStackedLayout(self.ui.games_group)
- self.games_spinner = WaitingSpinner(self.ui.games_group)
- self.games_flow = QWidget(self.ui.games_group)
- self.games_flow.setLayout(FlowLayout(self.games_flow))
- self.games_flow.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.games_layout.addWidget(self.games_spinner)
- self.games_layout.addWidget(self.games_flow)
-
- self.games_spinner.start()
- self.games_layout.setCurrentWidget(self.games_spinner)
+ self.browse_scrollarea = QScrollArea(self)
+ self.browse_scrollarea.setWidgetResizable(True)
+ self.browse_scrollarea.setFrameStyle(QFrame.NoFrame | QFrame.Plain)
+ self.browse_container = QWidget(self.browse_scrollarea)
+ browse_contailer_layout = QVBoxLayout(self.browse_container)
+ browse_contailer_layout.setContentsMargins(0, 0, 3, 0)
+ self.browse_container.setLayout(browse_contailer_layout)
+ self.browse_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ self.browse_scrollarea.setWidget(self.browse_container)
+
+ # self.free_scrollarea = QScrollArea(self.browse_container)
+ # self.free_scrollarea.setWidgetResizable(True)
+ # self.free_scrollarea.setFrameStyle(QFrame.NoFrame | QFrame.Plain)
+ # self.free_container = QWidget(self.free_scrollarea)
+ # free_container_layout = QHBoxLayout(self.free_container)
+ # free_container_layout.setContentsMargins(0, 0, 0, 3)
+ # self.free_container.setLayout(free_container_layout)
+ # self.free_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ # self.free_scrollarea.setWidget(self.free_container)
+ #
+ # self.browse_container.layout().addWidget(self.free_scrollarea)
+
+ self.discounts_group = ShopGroupBox(self.tr("Discounts from your wishlist"), FlowLayout, self)
+ self.browse_container.layout().addWidget(self.discounts_group)
+ self.discounts_group.loading(True)
+
+ self.games_group = ShopGroupBox(self.tr("Games"), FlowLayout, self)
+ self.browse_container.layout().addWidget(self.games_group)
+ self.games_group.loading(True)
+ self.games_group.setVisible(False)
+
+ self.browse_container.layout().addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding))
+
+ self.search_scrollarea = SearchResults(self.api_core, self)
self.search_bar = ButtonLineEdit(
"fa.search", placeholder_text=self.tr("Search Games")
)
- self.ui.main_layout.addWidget(self.search_bar, 0, 0)
+ self.ui.left_layout.addWidget(self.search_bar)
+
+ self.browse_stack = SlidingStackedWidget(self)
+ self.browse_stack.setDirection(Qt.Vertical)
+ self.browse_stack.addWidget(self.browse_scrollarea)
+ self.browse_stack.addWidget(self.search_scrollarea)
+ self.ui.left_layout.addWidget(self.browse_stack)
# self.search_bar.textChanged.connect(self.search_games)
@@ -102,8 +119,8 @@ def update_wishlist(self):
self.api_core.get_wishlist(self.add_wishlist_items)
def add_wishlist_items(self, wishlist: List[WishlistItemModel]):
- for w in self.discounts_flow.findChildren(QWidget, options=Qt.FindDirectChildrenOnly):
- self.discounts_flow.layout().removeWidget(w)
+ for w in self.discounts_group.findChildren(QWidget, options=Qt.FindDirectChildrenOnly):
+ self.discounts_group.layout().removeWidget(w)
w.deleteLater()
# if wishlist and wishlist[0] == "error":
@@ -126,50 +143,46 @@ def add_wishlist_items(self, wishlist: List[WishlistItemModel]):
if game.offer.price.total_price["discount"] > 0:
w = GameWidget(self.api_core.cached_manager, game.offer)
w.show_info.connect(self.show_game)
- self.discounts_flow.layout().addWidget(w)
+ self.discounts_group.layout().addWidget(w)
discounts += 1
except Exception as e:
logger.warning(f"{game} {e}")
continue
- self.ui.discounts_group.setVisible(discounts > 0)
- self.discounts_layout.setCurrentWidget(self.discounts_flow)
+ self.discounts_group.setVisible(discounts > 0)
+ self.discounts_group.loading(False)
# FIXME: FlowLayout doesn't update on adding widget
- self.discounts_flow.layout().update()
+ self.discounts_group.layout().update()
def add_free_games(self, free_games: List[CatalogOfferModel]):
- for w in self.ui.free_container.layout().findChildren(QGroupBox, options=Qt.FindDirectChildrenOnly):
- self.ui.free_container.layout().removeWidget(w)
+ for w in self.browse_container.layout().findChildren(QGroupBox, options=Qt.FindDirectChildrenOnly):
+ self.browse_container.layout().removeWidget(w)
w.deleteLater()
- if free_games and free_games[0] == "error":
- self.ui.free_container.layout().addWidget(
- QLabel(self.tr("Failed to fetch free games: {}").format(free_games[1]))
- )
- btn = QPushButton(self.tr("Reload"))
- self.ui.free_container.layout().addWidget(btn)
- btn.clicked.connect(
- lambda: self.api_core.get_free_games(self.add_free_games)
- )
- self.ui.free_container.setEnabled(True)
- return
+ # if free_games and free_games[0] == "error":
+ # self.ui.free_container.layout().addWidget(
+ # QLabel(self.tr("Failed to fetch free games: {}").format(free_games[1]))
+ # )
+ # btn = QPushButton(self.tr("Reload"))
+ # self.ui.free_container.layout().addWidget(btn)
+ # btn.clicked.connect(
+ # lambda: self.api_core.get_free_games(self.add_free_games)
+ # )
+ # self.ui.free_container.setEnabled(True)
+ # return
- self.free_games_now = QGroupBox(self.tr("Free now"), parent=self.ui.free_container)
- free_games_now_layout = QHBoxLayout(self.free_games_now)
- # free_games_now_layout.setContentsMargins(0, 0, 0, 0)
- self.free_games_now.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
- self.free_games_now.setLayout(free_games_now_layout)
- self.ui.free_container.layout().addWidget(self.free_games_now)
+ free_games_now = ShopGroupBox(self.tr("Free now"), layouting=QHBoxLayout, parent=self.browse_container)
+ free_games_now.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ # self.free_games_now.setLayout(free_games_now_layout)
+ self.browse_container.layout().insertWidget(0, free_games_now)
- self.free_games_next = QGroupBox(self.tr("Free next week"), parent=self.ui.free_container)
- free_games_next_layout = QHBoxLayout(self.free_games_next)
- # free_games_next_layout.setContentsMargins(0, 0, 0, 0)
- self.free_games_next.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
- self.free_games_next.setLayout(free_games_next_layout)
- self.ui.free_container.layout().addWidget(self.free_games_next)
+ free_games_next = ShopGroupBox(self.tr("Free next week"), layouting=QHBoxLayout, parent=self.browse_container)
+ free_games_next.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ # self.free_games_next.setLayout(free_games_next_layout)
+ self.browse_container.layout().insertWidget(1, free_games_next)
date = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
- free_games_now = []
- coming_free_games = []
+ free_now_list = []
+ free_next_list = []
for game in free_games:
try:
if (
@@ -177,11 +190,11 @@ def add_free_games(self, free_games: List[CatalogOfferModel]):
and game.price.total_price["fmtPrice"]["originalPrice"]
!= game.price.total_price["fmtPrice"]["discountPrice"]
):
- free_games_now.append(game)
+ free_now_list.append(game)
continue
if game.title == "Mystery Game":
- coming_free_games.append(game)
+ free_next_list.append(game)
continue
except KeyError as e:
logger.warning(str(e))
@@ -206,39 +219,43 @@ def add_free_games(self, free_games: List[CatalogOfferModel]):
continue
if start_date > date:
- coming_free_games.append(game)
+ free_next_list.append(game)
# free games now
now_free = 0
- for free_game in free_games_now:
+ for free_game in free_now_list:
w = GameWidget(self.api_core.cached_manager, free_game)
w.show_info.connect(self.show_game)
- self.free_games_now.layout().addWidget(w)
- self.free_game_widgets.append(w)
+ free_games_now.layout().addWidget(w)
+ # self.free_game_widgets.append(w)
now_free += 1
if now_free == 0:
- self.free_games_now.layout().addWidget(
+ free_games_now.layout().addWidget(
QLabel(self.tr("Could not find current free game"))
)
+ free_games_now.loading(False)
# free games next week
- for free_game in coming_free_games:
+ for free_game in free_next_list:
w = GameWidget(self.api_core.cached_manager, free_game)
if free_game.title != "Mystery Game":
w.show_info.connect(self.show_game)
- self.free_games_next.layout().addWidget(w)
+ free_games_next.layout().addWidget(w)
+ free_games_next.loading(False)
# self.coming_free_games.setFixedWidth(int(40 + len(coming_free_games) * 300))
- self.ui.free_scrollarea.setMinimumHeight(
- self.free_games_now.sizeHint().height()
- + self.ui.free_container.layout().contentsMargins().top()
- + self.ui.free_container.layout().contentsMargins().bottom()
- + self.ui.free_scrollarea.horizontalScrollBar().sizeHint().height()
- )
- self.ui.free_scrollarea.setEnabled(True)
+ # self.free_scrollarea.setMinimumHeight(
+ # free_games_now.sizeHint().height()
+ # + self.free_container.layout().contentsMargins().top()
+ # + self.free_container.layout().contentsMargins().bottom()
+ # + self.free_scrollarea.horizontalScrollBar().sizeHint().height()
+ # )
+ # self.free_scrollarea.setEnabled(True)
def show_search_results(self):
if self.search_bar.text():
- self.show_info.emit(self.search_bar.text())
+ self.browse_stack.slideInWidget(self.search_scrollarea)
+ self.search_scrollarea.load_results(self.search_bar.text())
+ # self.show_info.emit(self.search_bar.text())
def init_filter(self):
self.ui.none_price.toggled.connect(
@@ -299,6 +316,7 @@ def init_filter(self):
)
def reset_filters(self):
+ self.browse_stack.slideInWidget(self.browse_scrollarea)
self.update_games_allowed = False
for cb in self.checkboxes:
cb.setChecked(False)
@@ -334,14 +352,14 @@ def prepare_request(
if removed_type and removed_type in self.types:
self.types.remove(removed_type)
if (self.types or self.price) or self.tags or self.ui.on_discount.isChecked():
- self.ui.free_scrollarea.setVisible(False)
- self.ui.discounts_group.setVisible(False)
+ # self.free_scrollarea.setVisible(False)
+ self.discounts_group.setVisible(False)
else:
- self.ui.free_scrollarea.setVisible(True)
- if len(self.ui.discounts_group.layout().children()) > 0:
- self.ui.discounts_group.setVisible(True)
+ # self.free_scrollarea.setVisible(True)
+ if len(self.discounts_group.layout().children()) > 0:
+ self.discounts_group.setVisible(True)
- self.games_layout.setCurrentWidget(self.games_spinner)
+ self.games_group.loading(True)
browse_model = SearchStoreQuery(
language=self.core.language_code,
@@ -357,22 +375,22 @@ def prepare_request(
self.api_core.browse_games(browse_model, self.show_games)
def show_games(self, data):
- for w in self.games_flow.findChildren(QWidget, options=Qt.FindDirectChildrenOnly):
- self.games_flow.layout().removeWidget(w)
+ for w in self.games_group.findChildren(QWidget, options=Qt.FindDirectChildrenOnly):
+ self.games_group.layout().removeWidget(w)
w.deleteLater()
if data:
for game in data:
w = GameWidget(self.api_core.cached_manager, game)
w.show_info.connect(self.show_game)
- self.games_flow.layout().addWidget(w)
+ self.games_group.layout().addWidget(w)
else:
- self.games_flow.layout().addWidget(
+ self.games_group.layout().addWidget(
QLabel(self.tr("Could not get games matching the filter"))
)
- self.games_layout.setCurrentWidget(self.games_flow)
+ self.games_group.loading(False)
# FIXME: FlowLayout doesn't update on adding widget
- self.games_flow.layout().update()
+ self.games_group.layout().update()
class CheckBox(QCheckBox):
diff --git a/rare/components/tabs/store/wishlist.py b/rare/components/tabs/store/wishlist.py
index b8fe7277b..abb9f0f21 100644
--- a/rare/components/tabs/store/wishlist.py
+++ b/rare/components/tabs/store/wishlist.py
@@ -5,11 +5,11 @@
from rare.ui.components.tabs.store.wishlist import Ui_Wishlist
from rare.utils.misc import icon
-from rare.widgets.side_tab import SideTabContents
from rare.widgets.flow_layout import FlowLayout
-from .shop_api_core import ShopApiCore
-from .game_widgets import WishlistWidget
+from rare.widgets.side_tab import SideTabContents
from .api.models.response import WishlistItemModel, CatalogOfferModel
+from .game_widgets import WishlistWidget
+from .shop_api_core import ShopApiCore
class Wishlist(QWidget, SideTabContents):
diff --git a/rare/ui/components/tabs/store/store.py b/rare/ui/components/tabs/store/store.py
index 14ea03df0..f3b0ef4a5 100644
--- a/rare/ui/components/tabs/store/store.py
+++ b/rare/ui/components/tabs/store/store.py
@@ -16,8 +16,16 @@ def setupUi(self, ShopWidget):
ShopWidget.setObjectName("ShopWidget")
ShopWidget.resize(788, 662)
ShopWidget.setWindowTitle("Store")
- self.main_layout = QtWidgets.QGridLayout(ShopWidget)
+ self.main_layout = QtWidgets.QHBoxLayout(ShopWidget)
self.main_layout.setObjectName("main_layout")
+ self.left_layout = QtWidgets.QVBoxLayout()
+ self.left_layout.setObjectName("left_layout")
+ self.main_layout.addLayout(self.left_layout)
+ self.right_layout = QtWidgets.QVBoxLayout()
+ self.right_layout.setObjectName("right_layout")
+ self.reset_button = QtWidgets.QPushButton(ShopWidget)
+ self.reset_button.setObjectName("reset_button")
+ self.right_layout.addWidget(self.reset_button)
self.filter_scrollarea = QtWidgets.QScrollArea(ShopWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
@@ -89,59 +97,15 @@ def setupUi(self, ShopWidget):
self.others_layout.setObjectName("others_layout")
self.filter_container_layout.addWidget(self.others_group)
self.filter_scrollarea.setWidget(self.filter_container)
- self.main_layout.addWidget(self.filter_scrollarea, 1, 1, 1, 1)
- self.reset_button = QtWidgets.QPushButton(ShopWidget)
- self.reset_button.setObjectName("reset_button")
- self.main_layout.addWidget(self.reset_button, 0, 1, 1, 1)
- self.games_scrollarea = QtWidgets.QScrollArea(ShopWidget)
- self.games_scrollarea.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.games_scrollarea.setFrameShadow(QtWidgets.QFrame.Plain)
- self.games_scrollarea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
- self.games_scrollarea.setWidgetResizable(True)
- self.games_scrollarea.setObjectName("games_scrollarea")
- self.games_container = QtWidgets.QWidget()
- self.games_container.setGeometry(QtCore.QRect(0, 0, 628, 618))
- self.games_container.setObjectName("games_container")
- self.games_container_layout = QtWidgets.QVBoxLayout(self.games_container)
- self.games_container_layout.setContentsMargins(0, 0, 3, 0)
- self.games_container_layout.setObjectName("games_container_layout")
- self.free_scrollarea = QtWidgets.QScrollArea(self.games_container)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.free_scrollarea.sizePolicy().hasHeightForWidth())
- self.free_scrollarea.setSizePolicy(sizePolicy)
- self.free_scrollarea.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.free_scrollarea.setFrameShadow(QtWidgets.QFrame.Plain)
- self.free_scrollarea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
- self.free_scrollarea.setWidgetResizable(True)
- self.free_scrollarea.setObjectName("free_scrollarea")
- self.free_container = QtWidgets.QWidget()
- self.free_container.setGeometry(QtCore.QRect(0, 0, 16, 16))
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.free_container.sizePolicy().hasHeightForWidth())
- self.free_container.setSizePolicy(sizePolicy)
- self.free_container.setObjectName("free_container")
- self.free_container_layout = QtWidgets.QHBoxLayout(self.free_container)
- self.free_container_layout.setContentsMargins(0, 0, 0, 3)
- self.free_container_layout.setObjectName("free_container_layout")
- self.free_scrollarea.setWidget(self.free_container)
- self.games_container_layout.addWidget(self.free_scrollarea)
- self.discounts_group = QtWidgets.QGroupBox(self.games_container)
- self.discounts_group.setObjectName("discounts_group")
- self.games_container_layout.addWidget(self.discounts_group)
- self.games_group = QtWidgets.QGroupBox(self.games_container)
- self.games_group.setObjectName("games_group")
- self.games_container_layout.addWidget(self.games_group)
- self.games_scrollarea.setWidget(self.games_container)
- self.main_layout.addWidget(self.games_scrollarea, 1, 0, 1, 1)
+ self.right_layout.addWidget(self.filter_scrollarea)
+ self.main_layout.addLayout(self.right_layout)
+ self.main_layout.setStretch(0, 1)
self.retranslateUi(ShopWidget)
def retranslateUi(self, ShopWidget):
_translate = QtCore.QCoreApplication.translate
+ self.reset_button.setText(_translate("ShopWidget", "Reset filters"))
self.price_group.setTitle(_translate("ShopWidget", "Price"))
self.none_price.setText(_translate("ShopWidget", "None"))
self.free_button.setText(_translate("ShopWidget", "Free"))
@@ -154,9 +118,6 @@ def retranslateUi(self, ShopWidget):
self.genre_group.setTitle(_translate("ShopWidget", "Genre"))
self.type_group.setTitle(_translate("ShopWidget", "Type"))
self.others_group.setTitle(_translate("ShopWidget", "Other tags"))
- self.reset_button.setText(_translate("ShopWidget", "Reset filters"))
- self.discounts_group.setTitle(_translate("ShopWidget", "Discounts from your wishlist"))
- self.games_group.setTitle(_translate("ShopWidget", "Games"))
if __name__ == "__main__":
diff --git a/rare/ui/components/tabs/store/store.ui b/rare/ui/components/tabs/store/store.ui
index c46a8bf19..edd268a9b 100644
--- a/rare/ui/components/tabs/store/store.ui
+++ b/rare/ui/components/tabs/store/store.ui
@@ -13,267 +13,168 @@
Store
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::NoFrame
-
-
- QFrame::Plain
-
-
- Qt::ScrollBarAlwaysOff
-
-
- QAbstractScrollArea::AdjustToContents
-
-
- true
-
-
-
-
- 0
- 0
- 142
- 390
-
-
-
-
- 0
- 0
-
-
-
-
- 0
+
+
-
+
+
+ -
+
+
-
+
+
+ Reset filters
-
- 0
+
+
+ -
+
+
+
+ 0
+ 0
+
-
- 3
+
+ QFrame::NoFrame
-
- 0
+
+ QFrame::Plain
-
-
-
-
- Price
-
-
-
-
-
-
- None
-
-
- true
-
-
-
- -
-
-
- Free
-
-
-
- -
-
-
- Under 10
-
-
-
- -
-
-
- Under 20
-
-
-
- -
-
-
- Under 30
-
-
-
- -
-
-
- 14.99 and above
-
-
-
- -
-
-
- Discount
-
-
-
-
-
-
- -
-
-
- Platform
-
-
-
-
- -
-
-
- Genre
-
-
-
-
- -
-
-
- Type
-
-
-
-
- -
-
-
- Other tags
-
-
-
-
-
-
-
-
- -
-
-
- Reset filters
-
-
-
- -
-
-
- QFrame::NoFrame
-
-
- QFrame::Plain
-
-
- QAbstractScrollArea::AdjustToContents
-
-
- true
-
-
-
-
- 0
- 0
- 628
- 618
-
-
-
-
- 0
-
-
- 0
+
+ Qt::ScrollBarAlwaysOff
-
- 3
+
+ QAbstractScrollArea::AdjustToContents
-
- 0
+
+ true
-
-
-
-
-
- 0
- 0
-
-
-
- QFrame::NoFrame
+
+
+
+ 0
+ 0
+ 142
+ 390
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
-
- QFrame::Plain
+
+ 0
-
- Qt::ScrollBarAlwaysOff
+
+ 3
-
- true
+
+ 0
-
-
-
- 0
- 0
- 16
- 16
-
-
-
-
- 0
- 0
-
-
-
-
- 0
+
-
+
+
+ Price
-
- 0
+
+
-
+
+
+ None
+
+
+ true
+
+
+
+ -
+
+
+ Free
+
+
+
+ -
+
+
+ Under 10
+
+
+
+ -
+
+
+ Under 20
+
+
+
+ -
+
+
+ Under 30
+
+
+
+ -
+
+
+ 14.99 and above
+
+
+
+ -
+
+
+ Discount
+
+
+
+
+
+
+ -
+
+
+ Platform
-
- 0
+
+
+
+ -
+
+
+ Genre
-
- 3
+
+
+
+ -
+
+
+ Type
-
-
-
-
- -
-
-
- Discounts from your wishlist
-
-
-
- -
-
-
- Games
-
-
-
-
-
-
+
+
+
+ -
+
+
+ Other tags
+
+
+
+
+
+
+
+
+
diff --git a/rare/utils/qt_requests.py b/rare/utils/qt_requests.py
index b859fa61c..3a88903eb 100644
--- a/rare/utils/qt_requests.py
+++ b/rare/utils/qt_requests.py
@@ -67,7 +67,7 @@ def __prepare_request(self, item: RequestQueueItem) -> QNetworkRequest:
def __post(self, item: RequestQueueItem):
request = self.__prepare_request(item)
- payload = orjson.dumps(item.payload)
+ payload = orjson.dumps(item.payload) # pylint: disable=maybe-no-member
reply = self.manager.post(request, payload)
reply.errorOccurred.connect(self.__on_error)
self.__active_requests[reply] = item
@@ -128,7 +128,7 @@ def __on_finished(self, reply: QNetworkReply):
maintype, subtype = mimetype.split("/")
bin_data = reply.readAll().data()
if mimetype == "application/json":
- data = orjson.loads(bin_data)
+ data = orjson.loads(bin_data) # pylint: disable=maybe-no-member
elif maintype == "image":
data = bin_data
else: