Include version & last_tested info

This commit is contained in:
faith 2024-12-06 13:25:20 +08:00
commit 3862ed6a59
5 changed files with 66 additions and 41 deletions

View File

@ -1,12 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <iostream>
#include <QFileInfo>
#include <QMessageBox>
#include <QProgressDialog>
#include "common/path_util.h"
#include "compatibility_info.h"
#include <QProgressDialog>
#include <QMessageBox>
#include <QFileInfo>
CompatibilityInfoClass::CompatibilityInfoClass()
: m_network_manager(new QNetworkAccessManager(this)) {
@ -19,8 +19,9 @@ CompatibilityInfoClass::~CompatibilityInfoClass() = default;
void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
QFileInfo check_file(m_compatibility_filename);
const auto modified_delta = check_file.lastModified() - QDateTime::currentDateTime();
if (check_file.exists() && check_file.isFile() && std::chrono::duration_cast<std::chrono::minutes>(modified_delta).count() < 60) {
const auto modified_delta = QDateTime::currentDateTime() - check_file.lastModified();
if (check_file.exists() && check_file.isFile() &&
std::chrono::duration_cast<std::chrono::minutes>(modified_delta).count() < 60) {
if (LoadCompatibilityFile())
return;
QMessageBox::critical(parent, tr("Error"),
@ -46,9 +47,10 @@ void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
if (reply->error() != QNetworkReply::NoError) {
reply->deleteLater();
QMessageBox::critical(parent, tr("Error"),
tr("Unable to update compatibility data! Using old compatibility data..."));
//TODO: Try loading compatibility_file.json again
QMessageBox::critical(
parent, tr("Error"),
tr("Unable to update compatibility data! Using old compatibility data..."));
// Try loading compatibility_file.json again
LoadCompatibilityFile();
return;
}
@ -87,8 +89,7 @@ void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
dialog.reset();
});
connect(&dialog, &QProgressDialog::canceled, &future_watcher,
&QFutureWatcher<void>::cancel);
connect(&dialog, &QProgressDialog::canceled, &future_watcher, &QFutureWatcher<void>::cancel);
dialog.setRange(0, remaining_pages);
connect(&future_watcher, &QFutureWatcher<void>::progressValueChanged, &dialog,
&QProgressDialog::setValue);
@ -117,7 +118,7 @@ void CompatibilityInfoClass::WaitForReply(QNetworkReply* reply) {
return;
};
CompatibilityStatus CompatibilityInfoClass::GetCompatibilityStatus(const std::string& serial) {
CompatibilityEntry CompatibilityInfoClass::GetCompatibilityInfo(const std::string& serial) {
QString title_id = QString::fromStdString(serial);
if (m_compatibility_database.contains(title_id)) {
{
@ -125,13 +126,18 @@ CompatibilityStatus CompatibilityInfoClass::GetCompatibilityStatus(const std::st
QString os_string = OSTypeToString.at(static_cast<OSType>(os_int));
QJsonObject compatibility_obj = m_compatibility_database[title_id].toObject();
if (compatibility_obj.contains(os_string)) {
return LabelToCompatStatus.at(
compatibility_obj[os_string].toString());
QJsonObject compatibility_entry_obj = compatibility_obj[os_string].toObject();
CompatibilityEntry compatibility_entry{
LabelToCompatStatus.at(compatibility_entry_obj["status"].toString()),
compatibility_entry_obj["version"].toString(),
QDateTime::fromString(compatibility_entry_obj["last_tested"].toString(),
Qt::ISODate)};
return compatibility_entry;
}
}
}
}
return CompatibilityStatus::Unknown;
return CompatibilityEntry{CompatibilityStatus::Unknown};
}
bool CompatibilityInfoClass::LoadCompatibilityFile() {
@ -152,7 +158,6 @@ bool CompatibilityInfoClass::LoadCompatibilityFile() {
return true;
}
void CompatibilityInfoClass::ExtractCompatibilityInfo(QByteArray response) {
QJsonDocument json_doc(QJsonDocument::fromJson(response));
@ -187,13 +192,20 @@ void CompatibilityInfoClass::ExtractCompatibilityInfo(QByteArray response) {
}
}
QJsonValueRef compatibility_object_ref = m_compatibility_database[title_id];
// QJson does not support editing nested objects directly..
if (compatibility_object_ref.isNull()) {
compatibility_object_ref = QJsonObject({{current_os, compatibility_status}});
} else {
compatibility_object_ref.toObject()[current_os] = compatibility_status;
}
QJsonObject compatibility_obj = m_compatibility_database[title_id].toObject();
QJsonObject compatibility_data{
{{"status", compatibility_status},
{"last_tested", issue_obj["updated_at"]},
{"version", issue_obj["milestone"].isNull()
? "unknown"
: issue_obj["milestone"].toObject()["title"].toString()}}};
compatibility_obj[current_os] = compatibility_data;
m_compatibility_database[title_id] = compatibility_obj;
}
}

View File

@ -42,6 +42,12 @@ enum OSType {
Last
};
struct CompatibilityEntry {
CompatibilityStatus status;
QString version;
QDateTime last_tested;
};
class CompatibilityInfoClass : public QObject {
Q_OBJECT
public:
@ -75,7 +81,7 @@ public:
~CompatibilityInfoClass();
void UpdateCompatibilityDatabase(QWidget* parent = nullptr);
bool LoadCompatibilityFile();
CompatibilityStatus GetCompatibilityStatus(const std::string& serial);
CompatibilityEntry GetCompatibilityInfo(const std::string& serial);
void ExtractCompatibilityInfo(QByteArray response);
static void WaitForReply(QNetworkReply* reply);
QNetworkReply* FetchPage(int page_num);

View File

@ -8,8 +8,8 @@
#include "game_list_utils.h"
#include <QToolTip>
GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent)
: QTableWidget(parent), m_game_info(game_info_get), m_compat_info(compat_info_get) {
icon_size = Config::getIconSize();
@ -22,7 +22,7 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
this->verticalScrollBar()->installEventFilter(this);
this->verticalScrollBar()->setSingleStep(20);
this->horizontalScrollBar()->setSingleStep(20);
this->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
this->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
this->verticalHeader()->setVisible(false);
this->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
this->horizontalHeader()->setHighlightSections(false);
@ -44,8 +44,8 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
this->setHorizontalHeaderLabels(headers);
this->horizontalHeader()->setSortIndicatorShown(true);
this->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
this->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
this->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
this->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Fixed);
PopulateGameList();
connect(this, &QTableWidget::currentCellChanged, this, &GameListFrame::onCurrentCellChanged);
@ -108,9 +108,9 @@ void GameListFrame::PopulateGameList() {
SetTableItem(i, 6, QString::fromStdString(m_game_info->m_games[i].size));
SetTableItem(i, 7, QString::fromStdString(m_game_info->m_games[i].version));
m_game_info->m_games[i].compatibility_status =
m_compat_info->GetCompatibilityStatus(m_game_info->m_games[i].serial);
SetCompatibilityItem(i, 2, m_game_info->m_games[i].compatibility_status);
m_game_info->m_games[i].compatibility =
m_compat_info->GetCompatibilityInfo(m_game_info->m_games[i].serial);
SetCompatibilityItem(i, 2, m_game_info->m_games[i].compatibility);
QString playTime = GetPlayTime(m_game_info->m_games[i].serial);
if (playTime.isEmpty()) {
@ -213,7 +213,7 @@ void GameListFrame::ResizeIcons(int iconSize) {
this->horizontalHeader()->setSectionResizeMode(8, QHeaderView::ResizeToContents);
}
void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatus status) {
void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityEntry entry) {
QTableWidgetItem* item = new QTableWidgetItem();
QWidget* widget = new QWidget(this);
QGridLayout* layout = new QGridLayout(widget);
@ -221,7 +221,7 @@ void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatu
QColor color;
QString tooltip_string;
switch (status) {
switch (entry.status) {
case Unknown:
color = QStringLiteral("#000000");
tooltip_string = tr("Compatibility is untested");
@ -259,9 +259,9 @@ void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatu
QLabel* dotLabel = new QLabel("", widget);
dotLabel->setPixmap(circle_pixmap);
QLabel* label = new QLabel(m_compat_info->CompatStatusToString.at(status), widget);
QLabel* label = new QLabel(m_compat_info->CompatStatusToString.at(entry.status), widget);
label->setStyleSheet("color: white; font-size: 16px; font-weight: bold;");
label->setStyleSheet("color: white; font-size: 12px; font-weight: bold;");
// Create shadow effect
QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect();
@ -271,8 +271,13 @@ void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatu
label->setGraphicsEffect(shadowEffect); // Apply shadow effect to the QLabel
layout->addWidget(dotLabel, 0, 0, -1, 4);
layout->addWidget(label, 0, 4, -1, 4);
QLabel* version_label =
new QLabel(QString("%1, (%2)").arg(entry.last_tested.toString("yyyy-MM-dd"), entry.version), widget);
version_label->setStyleSheet("color: white; font-size: 10px;");
layout->addWidget(dotLabel, 0, 0, -1, 1);
layout->addWidget(label, 0, 1, 1, 1);
layout->addWidget(version_label, 1, 1, 1, 1);
layout->setAlignment(Qt::AlignLeft);
widget->setLayout(layout);
widget->setToolTip(tooltip_string);

View File

@ -18,7 +18,9 @@
class GameListFrame : public QTableWidget {
Q_OBJECT
public:
explicit GameListFrame(std::shared_ptr<GameInfoClass> game_info_get, std::shared_ptr<CompatibilityInfoClass> compat_info_get, QWidget* parent = nullptr);
explicit GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
QWidget* parent = nullptr);
Q_SIGNALS:
void GameListFrameClosed();
@ -34,7 +36,7 @@ public Q_SLOTS:
private:
void SetTableItem(int row, int column, QString itemStr);
void SetRegionFlag(int row, int column, QString itemStr);
void SetCompatibilityItem(int row, int column, CompatibilityStatus status);
void SetCompatibilityItem(int row, int column, CompatibilityEntry entry);
QString GetPlayTime(const std::string& serial);
QList<QAction*> m_columnActs;
GameInfoClass* game_inf_get = nullptr;
@ -66,7 +68,7 @@ public:
case 1:
return a.name < b.name;
case 2:
return a.compatibility_status < b.compatibility_status;
return a.compatibility.status < b.compatibility.status;
case 3:
return a.serial.substr(4) < b.serial.substr(4);
case 4:
@ -91,7 +93,7 @@ public:
case 1:
return a.name > b.name;
case 2:
return a.compatibility_status > b.compatibility_status;
return a.compatibility.status > b.compatibility.status;
case 3:
return a.serial.substr(4) > b.serial.substr(4);
case 4:

View File

@ -27,7 +27,7 @@ struct GameInfo {
std::string fw = "Unknown";
std::string play_time = "Unknown";
CompatibilityStatus compatibility_status = CompatibilityStatus::Unknown;
CompatibilityEntry compatibility = CompatibilityEntry{CompatibilityStatus::Unknown};
};
class GameListUtils {