From 691a16e9ad655fe80c7a0004f381c84d9d80dff0 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 7 Jun 2025 11:16:24 -0400 Subject: [PATCH] Add report issue dialog. --- app/reportissuedialog.cpp | 103 ++++++++++++++++++++++++++++++++++++++ app/reportissuedialog.h | 43 ++++++++++++++++ app/reportissuedialog.ui | 84 +++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 app/reportissuedialog.cpp create mode 100644 app/reportissuedialog.h create mode 100644 app/reportissuedialog.ui diff --git a/app/reportissuedialog.cpp b/app/reportissuedialog.cpp new file mode 100644 index 0000000..305a494 --- /dev/null +++ b/app/reportissuedialog.cpp @@ -0,0 +1,103 @@ +#include "reportissuedialog.h" +#include "qjsonarray.h" +#include "ui_reportissuedialog.h" + +#include +#include +#include +#include + +ReportIssueDialog::ReportIssueDialog(const QString &giteaBaseUrl, + const QString &repoOwner, + const QString &repoName, + const QString &accessToken, + QWidget *parent) : + QDialog(parent), + ui(new Ui::ReportIssueDialog), + networkManager(new QNetworkAccessManager(this)), + giteaBaseUrl(giteaBaseUrl), + repoOwner(repoOwner), + repoName(repoName), + accessToken(accessToken) +{ + ui->setupUi(this); + + connect(networkManager, &QNetworkAccessManager::finished, this, &ReportIssueDialog::onNetworkReplyFinished); +} + +ReportIssueDialog::~ReportIssueDialog() +{ + delete ui; +} + +void ReportIssueDialog::on_buttonSend_clicked() +{ + QString title = ui->lineEditSummary->text().trimmed(); + QString details = ui->textEditDetails->toPlainText().trimmed(); + QString contact = ui->lineEditContact->text().trimmed(); + + if (title.isEmpty()) { + QMessageBox::warning(this, tr("Input Error"), tr("Please enter a summary/title for the issue.")); + return; + } + + QString body = details; + if (!contact.isEmpty()) { + body += QString("\n\nContact info:\n%1").arg(contact); + } + + ui->buttonSend->setEnabled(false); + sendIssueReport(title, body, contact); +} + +void ReportIssueDialog::on_buttonCancel_clicked() +{ + reject(); +} + +void ReportIssueDialog::sendIssueReport(const QString &title, const QString &body, const QString &/*contact*/) +{ + // Compose URL: e.g. https://gitea.example.com/api/v1/repos/{owner}/{repo}/issues + QUrl url(QString("%1/api/v1/repos/%2/%3/issues").arg(giteaBaseUrl).arg(repoOwner).arg(repoName)); + + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + if (!accessToken.isEmpty()) { + request.setRawHeader("Authorization", "token " + accessToken.toUtf8()); + } + + // Compose JSON body + QJsonObject json; + json["title"] = title; + json["body"] = body; + json["labels"] = QJsonArray{12}; + + QJsonDocument doc(json); + QByteArray data = doc.toJson(); + + networkManager->post(request, data); +} + +void ReportIssueDialog::onNetworkReplyFinished(QNetworkReply *reply) +{ + ui->buttonSend->setEnabled(true); + + QByteArray responseData = reply->readAll(); + QString responseStr = QString::fromUtf8(responseData); + + if (reply->error() != QNetworkReply::NoError) { + QString errorStr = reply->errorString(); + if (errorStr.isEmpty()) errorStr = "Unknown network error"; + QMessageBox::critical(this, tr("Error"), tr("Failed to send issue report:\n%1\nResponse:\n%2").arg(errorStr).arg(responseStr)); + } else { + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + if (status == 201) { + QMessageBox::information(this, tr("Success"), tr("Issue reported successfully!")); + accept(); + } else { + QMessageBox::warning(this, tr("Failed"), tr("Unexpected response from server (%1):\n%2").arg(status).arg(responseStr)); + } + } + reply->deleteLater(); +} diff --git a/app/reportissuedialog.h b/app/reportissuedialog.h new file mode 100644 index 0000000..5a0ed75 --- /dev/null +++ b/app/reportissuedialog.h @@ -0,0 +1,43 @@ +#ifndef REPORTISSUEDIALOG_H +#define REPORTISSUEDIALOG_H + +#include +#include +#include + +namespace Ui { +class ReportIssueDialog; +} + +class ReportIssueDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ReportIssueDialog(const QString &giteaBaseUrl, + const QString &repoOwner, + const QString &repoName, + const QString &accessToken, + QWidget *parent = nullptr); + ~ReportIssueDialog(); + +private slots: + void on_buttonSend_clicked(); + void on_buttonCancel_clicked(); + + void onNetworkReplyFinished(QNetworkReply *reply); + +private: + Ui::ReportIssueDialog *ui; + + QNetworkAccessManager *networkManager; + + QString giteaBaseUrl; + QString repoOwner; + QString repoName; + QString accessToken; + + void sendIssueReport(const QString &title, const QString &body, const QString &contact); +}; + +#endif // REPORTISSUEDIALOG_H diff --git a/app/reportissuedialog.ui b/app/reportissuedialog.ui new file mode 100644 index 0000000..94bacb3 --- /dev/null +++ b/app/reportissuedialog.ui @@ -0,0 +1,84 @@ + + + ReportIssueDialog + + + Report a Problem + + + + + + Please describe the problem you encountered. We’ll use this info to help fix it. + + + true + + + + + + + Summary (short title): + + + + + + + + + + Details (what happened?): + + + + + + + + + + Your contact (email or name, optional): + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + + + + Send Report + + + true + + + + + + + Cancel + + + + + + + + + +