add issues key to mod.json for specifying where to report issues for

mods
This commit is contained in:
HJfod 2022-09-29 15:17:02 +03:00
parent d9b7489d66
commit 9881d3e75f
8 changed files with 133 additions and 19 deletions

View file

@ -13,6 +13,7 @@
#include <type_traits>
#include <cocos2d.h>
#include "Setting.hpp"
#include <optional>
class InternalLoader;
class InternalMod;
@ -41,6 +42,11 @@ namespace geode {
bool isUnresolved() const;
};
struct IssuesInfo {
std::string m_info;
std::optional<std::string> m_url;
};
/**
* Represents all the data gatherable
* from mod.json
@ -113,9 +119,13 @@ namespace geode {
*/
std::string m_supportInfo = "";
/**
* Git Repository of the mod.
* Git Repository of the mod
*/
std::string m_repository = "";
/**
* Info about where users should report issues and request help
*/
std::optional<IssuesInfo> m_issues;
/**
* Dependencies
*/

View file

@ -11,22 +11,32 @@ namespace geode {
class MDPopup : public Popup<
std::string const&,
std::string const&,
std::string const&
const char*,
const char*,
std::function<void(bool)>
> {
protected:
std::function<void(bool)> m_onClick = nullptr;
bool setup(
std::string const& title,
std::string const& info,
std::string const& btn
const char* btn1,
const char* btn2,
std::function<void(bool)> onClick
) override;
void onBtn(CCObject*);
static float estimateHeight(std::string const& content);
public:
static MDPopup* create(
std::string const& title,
std::string const& content,
std::string const& button
const char* btn1,
const char* btn2 = nullptr,
std::function<void(bool)> onClick = nullptr
);
};
}

View file

@ -52,5 +52,9 @@
"name": "Show Platform Console",
"description": "Show the native console (if one exists). <cr>This setting is meant for developers</c>."
}
},
"issues": {
"info": "Post your issues on the <cp>Geode Github Repository</c>. <cy>Please follow the standard issue format</c>.",
"url": "https://github.com/geode-sdk/geode/issues/new"
}
}

View file

@ -5,6 +5,8 @@
#include <Index.hpp>
#include "../ui/internal/list/ModListLayer.hpp"
#include <Geode/ui/MDPopup.hpp>
#include <InternalMod.hpp>
#include "../ui/internal/info/ModInfoLayer.hpp"
USE_GEODE_NAMESPACE();
@ -188,14 +190,9 @@ class $modify(CustomMenuLayer, MenuLayer) {
"No", "Send",
[](auto, bool btn2) {
if (btn2) {
MDPopup::create(
"Crash Report",
"Please send the latest crash report file from `" +
Loader::get()->getCrashLogDirectory().string() + "` to the "
"[#support](https://discord.com/channels/911701438269386882/979352389985390603) "
"channnel in the [Geode Discord Server](https://discord.gg/9e43WMKzhp)\n\n",
"OK"
)->show();
ModInfoLayer::showIssueReportPopup(
InternalMod::get()->getModInfo()
);
}
},
false

View file

@ -77,6 +77,13 @@ Result<ModInfo> ModInfo::createFromSchemaV010(ModJson const& rawJson) {
}
}
if (auto issues = root.has("issues").obj()) {
IssuesInfo issuesInfo;
issues.needs("info").into(issuesInfo.m_info);
issues.has("url").intoAs<std::string>(issuesInfo.m_url);
info.m_issues = issuesInfo;
}
root.has("binary").asOneOf<value_t::string, value_t::object>();
bool autoEndBinaryName = true;

View file

@ -192,6 +192,22 @@ bool ModInfoLayer::init(ModObject* obj, ModListView* list) {
infoBtn->setPosition(size.width / 2 - 25.f, size.height / 2 - 25.f);
m_buttonMenu->addChild(infoBtn);
// issue report button
if (m_info.m_issues) {
auto issuesBtnSpr = ButtonSprite::create(
"Report an Issue", "goldFont.fnt", "GJ_button_04.png", .8f
);
issuesBtnSpr->setScale(.75f);
auto issuesBtn = CCMenuItemSpriteExtra::create(
issuesBtnSpr, this, makeMenuSelector([this](CCObject*) {
ModInfoLayer::showIssueReportPopup(m_info);
})
);
issuesBtn->setPosition(0.f, -size.height / 2 + 25.f);
m_buttonMenu->addChild(issuesBtn);
}
if (isInstalledMod) {
auto settingsSpr = CCSprite::createWithSpriteFrameName(
@ -741,3 +757,33 @@ CCNode* ModInfoLayer::createLogoSpr(IndexItem const& item) {
return spr;
}
void ModInfoLayer::showIssueReportPopup(ModInfo const& info) {
if (info.m_issues) {
MDPopup::create(
"Issue Report",
info.m_issues.value().m_info + "\n\n"
"If your issue relates to a <cr>game crash</c>, <cb>please include</c> the "
"latest crash log(s) from `" +
Loader::get()->getCrashLogDirectory().string() + "`",
"OK", (info.m_issues.value().m_url ? "Open URL" : ""),
[info](bool btn2) {
if (btn2) {
web::openLinkInBrowser(info.m_issues.value().m_url.value());
}
}
)->show();
} else {
MDPopup::create(
"Issue Report",
"Please report your issue on the "
"[#support](https://discord.com/channels/911701438269386882/979352389985390603) "
"channnel in the [Geode Discord Server](https://discord.gg/9e43WMKzhp)\n\n"
"If your issue relates to a <cr>game crash</c>, <cb>please include</c> the "
"latest crash log(s) from `" +
Loader::get()->getCrashLogDirectory().string() + "`",
"OK"
)->show();
}
}

View file

@ -67,6 +67,8 @@ public:
static ModInfoLayer* create(Mod* mod, ModListView* list);
static ModInfoLayer* create(ModObject* obj, ModListView* list);
static void showIssueReportPopup(ModInfo const& info);
static CCNode* createLogoSpr(ModObject* modObj);
static CCNode* createLogoSpr(Mod* mod);
static CCNode* createLogoSpr(IndexItem const& item);

View file

@ -6,10 +6,14 @@ USE_GEODE_NAMESPACE();
bool MDPopup::setup(
std::string const& title,
std::string const& info,
std::string const& btnText
const char* btn1Text,
const char* btn2Text,
std::function<void(bool)> onClick
) {
this->setTitle(title.c_str(), "goldFont.fnt", .9f, 33.f);
m_onClick = onClick;
auto winSize = CCDirector::sharedDirector()->getWinSize();
auto contentSize = CCSize {
@ -20,18 +24,50 @@ bool MDPopup::setup(
content->setPosition(winSize / 2 - contentSize / 2);
m_mainLayer->addChild(content);
auto btnSpr = ButtonSprite::create(btnText.c_str());
btnSpr->setScale(1.f);
auto btnSpr = ButtonSprite::create(btn1Text);
auto btn = CCMenuItemSpriteExtra::create(
btnSpr, this, menu_selector(MDPopup::onClose)
btnSpr, this, menu_selector(MDPopup::onBtn)
);
btn->setPosition(.0f, -m_size.height / 2 + 35.f);
btn->setTag(0);
m_buttonMenu->addChild(btn);
if (btn2Text) {
auto btn2Spr = ButtonSprite::create(btn2Text);
auto btn2 = CCMenuItemSpriteExtra::create(
btn2Spr, this, menu_selector(MDPopup::onBtn)
);
btn2->setTag(1);
m_buttonMenu->addChild(btn2);
auto fullBtnWidth = btnSpr->getContentSize().width +
10.f + btn2Spr->getContentSize().width;
btn->setPosition(
-fullBtnWidth / 2 + btnSpr->getContentSize().width / 2,
-m_size.height / 2 + 35.f
);
btn2->setPosition(
fullBtnWidth / 2 - btn2Spr->getContentSize().width / 2,
-m_size.height / 2 + 35.f
);
}
// position button in the middle
else {
btn->setPosition(.0f, -m_size.height / 2 + 35.f);
}
return true;
}
void MDPopup::onBtn(CCObject* sender) {
if (m_onClick) {
m_onClick(sender->getTag());
}
this->onClose(nullptr);
}
float MDPopup::estimateHeight(std::string const& content) {
return clamp(string::count(content, '\n') * 30.f, 200.f, 360.f);
}
@ -39,12 +75,14 @@ float MDPopup::estimateHeight(std::string const& content) {
MDPopup* MDPopup::create(
std::string const& title,
std::string const& content,
std::string const& button
const char* btn1,
const char* btn2,
std::function<void(bool)> onClick
) {
auto ret = new MDPopup();
if (ret && ret->init(
320.f, MDPopup::estimateHeight(content),
title, content, button,
title, content, btn1, btn2, onClick,
"square01_001.png", { 0, 0, 94, 94 }
)) {
ret->autorelease();