NOISSUE improve Modrinth description's page rendering

This commit is contained in:
Petr Mrázek 2022-07-19 21:46:28 +02:00
parent e5c962b7b9
commit ec498074c1
7 changed files with 140 additions and 11 deletions

View File

@ -730,6 +730,8 @@ SET(LAUNCHER_SOURCES
ui/pages/modplatform/modrinth/ModrinthData.h
ui/pages/modplatform/modrinth/ModrinthModel.cpp
ui/pages/modplatform/modrinth/ModrinthModel.h
ui/pages/modplatform/modrinth/ModrinthDocument.cpp
ui/pages/modplatform/modrinth/ModrinthDocument.h
ui/pages/modplatform/modrinth/ModrinthPage.cpp
ui/pages/modplatform/modrinth/ModrinthPage.h

View File

@ -57,7 +57,7 @@ public:
HoeDown()
{
renderer = hoedown_html_renderer_new((hoedown_html_flags) 0,0);
document = hoedown_document_new(renderer, (hoedown_extensions) 0, 8);
document = hoedown_document_new(renderer, (hoedown_extensions) HOEDOWN_EXT_TABLES, 8);
}
~HoeDown()
{

View File

@ -0,0 +1,80 @@
/*
* Copyright 2022 Petr Mrázek
*
* This source is subject to the Microsoft Permissive License (MS-PL).
* Please see the COPYING.md file for more information.
*/
#include "ModrinthDocument.h"
#include <HoeDown.h>
#include <QPixmapCache>
#include <QDebug>
#include <net/NetJob.h>
#include <Application.h>
Modrinth::ModrinthDocument::ModrinthDocument(const QString &markdown, QObject* parent) : QTextDocument(parent) {
HoeDown hoedown;
// 100 MiB
QPixmapCache::setCacheLimit(102400);
setHtml(hoedown.process(markdown.toUtf8()));
}
QVariant Modrinth::ModrinthDocument::loadResource(int type, const QUrl& name) {
if(type == QTextDocument::ResourceType::ImageResource) {
auto pixmap = QPixmapCache::find(name.toString());
if(!pixmap) {
requestResource(name);
return QVariant();
}
return QVariant(*pixmap);
}
return QTextDocument::loadResource(type, name);
}
void Modrinth::ModrinthDocument::downloadFinished(const QString& key, const QPixmap& out) {
m_loading.remove(key);
QPixmapCache::insert(key, out);
emit layoutUpdateRequired();
}
void Modrinth::ModrinthDocument::downloadFailed(const QString& key) {
m_failed.append(key);
m_loading.remove(key);
}
void Modrinth::ModrinthDocument::requestResource(const QUrl& url) {
QString key = url.toString();
if(m_loading.contains(key) || m_failed.contains(key))
{
return;
}
qDebug() << "Loading resource" << key;
ImageLoad *load = new ImageLoad;
load->job = new NetJob(QString("Modrinth Image Download %1").arg(key), APPLICATION->network());
load->job->addNetAction(Net::Download::makeByteArray(url, &load->output));
load->key = key;
QObject::connect(load->job.get(), &NetJob::succeeded, this, [this, load] {
QPixmap pixmap;
if(!pixmap.loadFromData(load->output)) {
qDebug() << load->output;
downloadFailed(load->key);
}
if(pixmap.width() > 800) {
pixmap = pixmap.scaledToWidth(800);
}
downloadFinished(load->key, pixmap);
});
QObject::connect(load->job.get(), &NetJob::failed, this, [this, load]
{
downloadFailed(load->key);
});
load->job->start();
m_loading[key] = load;
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2022 Petr Mrázek
*
* This source is subject to the Microsoft Permissive License (MS-PL).
* Please see the COPYING.md file for more information.
*/
#pragma once
#include <QTextDocument>
#include <net/NetJob.h>
namespace Modrinth {
using Callback = std::function<void(QString)>;
struct ImageLoad {
QString key;
NetJob::Ptr job;
QByteArray output;
Callback handler;
};
class ModrinthDocument: public QTextDocument {
Q_OBJECT
public:
ModrinthDocument(const QString &markdown, QObject * parent = nullptr);
signals:
void layoutUpdateRequired();
protected:
QVariant loadResource(int type, const QUrl & name) override;
private:
void downloadFailed(const QString &key);
void downloadFinished(const QString &key, const QPixmap &out);
void requestResource(const QUrl &url);
private:
QMap<QString, ImageLoad *> m_loading;
QStringList m_failed;
};
}

View File

@ -17,12 +17,12 @@
#include "ModrinthModel.h"
#include "ModrinthPage.h"
#include "ModrinthDocument.h"
#include "ui/dialogs/NewInstanceDialog.h"
#include "ui_ModrinthPage.h"
#include <QKeyEvent>
#include <HoeDown.h>
#include <InstanceImportTask.h>
ModrinthPage::ModrinthPage(NewInstanceDialog *dialog, QWidget *parent) : QWidget(parent), ui(new Ui::ModrinthPage), dialog(dialog)
@ -133,14 +133,6 @@ void ModrinthPage::onPackDataChanged(const QString& id)
}
}
namespace {
QString processMarkdown(QString input)
{
HoeDown hoedown;
return hoedown.process(input.toUtf8());
}
}
QString versionToString(const Modrinth::Version& version) {
switch(version.type) {
case Modrinth::VersionType::Alpha: {
@ -171,7 +163,9 @@ void ModrinthPage::updateCurrentPackUI()
break;
}
case Modrinth::LoadState::Loaded: {
ui->packDescription->setText(processMarkdown(current.body));
auto document = new Modrinth::ModrinthDocument(current.body);
connect(document, &Modrinth::ModrinthDocument::layoutUpdateRequired, this, &ModrinthPage::forceDocumentLayout);
ui->packDescription->setDocument(document);
break;
}
}
@ -199,3 +193,7 @@ void ModrinthPage::updateCurrentPackUI()
}
suggestCurrent();
}
void ModrinthPage::forceDocumentLayout() {
ui->packDescription->document()->adjustSize();
}

View File

@ -64,6 +64,7 @@ private slots:
void onSelectionChanged(QModelIndex first, QModelIndex second);
void onVersionSelectionChanged(const QString & version);
void onPackDataChanged(const QString &id);
void forceDocumentLayout();
private:
void updateCurrentPackUI();

View File

@ -36,6 +36,9 @@
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>