mirror of
https://github.com/infiniteCable2/openpilot.git
synced 2026-08-05 00:05:57 +08:00
ui: update discord references and add forum widget (#1440)
* sunnylink: introduce community popup with QR code embedding - Added `SunnylinkCommunityPopup` widget to promote the sunnypilot Community Forum. - Integrated a QR code generator and display for quick access. - Updated `WiFiPromptWidget` to include a "Learn More" button triggering the community popup. * sunnylink: adjust community popup styling for better layout - Reduced font size of description text slightly for consistency. - Decreased QR code dimensions to improve visual balance. * Making more space out of thin air * sunnylink: update community references to use forum links - Replaced Discord links with Community Forum URLs for better alignment. - Improved clarity in sponsorship instructions.
This commit is contained in:
@@ -11,17 +11,18 @@ WiFiPromptWidget::WiFiPromptWidget(QWidget *parent) : QFrame(parent) {
|
||||
main_layout->setContentsMargins(56, 40, 56, 40);
|
||||
main_layout->setSpacing(42);
|
||||
|
||||
QLabel *title = new QLabel(tr("<span style='font-family: \"Noto Color Emoji\";'>🔥</span> Firehose Mode <span style='font-family: Noto Color Emoji;'>🔥</span>"));
|
||||
title->setStyleSheet("font-size: 64px; font-weight: 500;");
|
||||
community_popup = new SunnylinkCommunityPopup(this);
|
||||
QLabel *title = new QLabel(tr("sunnypilot Community"));
|
||||
title->setStyleSheet("font-size: 56px; font-weight: 500;");
|
||||
main_layout->addWidget(title);
|
||||
|
||||
QLabel *desc = new QLabel(tr("Maximize your training data uploads to improve openpilot's driving models."));
|
||||
QLabel *desc = new QLabel(tr("Need help or have ideas?<br><b>Join</b> our community now!"));
|
||||
desc->setStyleSheet("font-size: 40px; font-weight: 400;");
|
||||
desc->setWordWrap(true);
|
||||
main_layout->addWidget(desc);
|
||||
|
||||
QPushButton *settings_btn = new QPushButton(tr("Open"));
|
||||
connect(settings_btn, &QPushButton::clicked, [=]() { emit openSettings(1, "FirehosePanel"); });
|
||||
QPushButton *settings_btn = new QPushButton(tr("Learn More"));
|
||||
connect(settings_btn, &QPushButton::clicked, [=]() { community_popup->exec(); });
|
||||
settings_btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
font-size: 48px;
|
||||
|
||||
@@ -3,12 +3,17 @@
|
||||
#include <QFrame>
|
||||
#include <QWidget>
|
||||
|
||||
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h"
|
||||
|
||||
class WiFiPromptWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WiFiPromptWidget(QWidget* parent = 0);
|
||||
|
||||
private:
|
||||
SunnylinkCommunityPopup *community_popup;
|
||||
|
||||
signals:
|
||||
void openSettings(int index = 0, const QString ¶m = "");
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@ qt_src = [
|
||||
"sunnypilot/qt/offroad/settings/software_panel.cc",
|
||||
"sunnypilot/qt/offroad/settings/sunnylink_panel.cc",
|
||||
"sunnypilot/qt/offroad/settings/sunnylink/sponsor_widget.cc",
|
||||
"sunnypilot/qt/offroad/settings/sunnylink/community_widget.cc",
|
||||
"sunnypilot/qt/offroad/settings/trips_panel.cc",
|
||||
"sunnypilot/qt/offroad/settings/vehicle_panel.cc",
|
||||
"sunnypilot/qt/offroad/settings/visuals_panel.cc",
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Copyright (c) 2025-, sunnypilot contributors.
|
||||
*
|
||||
* This file is part of sunnypilot and is licensed under the MIT License.
|
||||
* See the LICENSE.md file in the root directory for more details.
|
||||
*/
|
||||
|
||||
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h"
|
||||
|
||||
#include "selfdrive/ui/sunnypilot/ui.h"
|
||||
#include "selfdrive/ui/sunnypilot/qt/util.h"
|
||||
|
||||
using qrcodegen::QrCode;
|
||||
|
||||
// --- SunnylinkCommunityQRWidget ---
|
||||
|
||||
SunnylinkCommunityQRWidget::SunnylinkCommunityQRWidget(QWidget* parent)
|
||||
: QWidget(parent) {}
|
||||
|
||||
void SunnylinkCommunityQRWidget::showEvent(QShowEvent *event) {
|
||||
updateQrCode(SUNNYLINK_COMMUNITY_URL);
|
||||
update();
|
||||
}
|
||||
|
||||
void SunnylinkCommunityQRWidget::updateQrCode(const QString &text) {
|
||||
QrCode qr = QrCode::encodeText(text.toUtf8().data(), QrCode::Ecc::LOW);
|
||||
qint32 sz = qr.getSize();
|
||||
QImage im(sz, sz, QImage::Format_RGB32);
|
||||
|
||||
QRgb black = qRgb(0, 0, 0);
|
||||
QRgb white = qRgb(255, 255, 255);
|
||||
for (int y = 0; y < sz; y++) {
|
||||
for (int x = 0; x < sz; x++) {
|
||||
im.setPixel(x, y, qr.getModule(x, y) ? black : white);
|
||||
}
|
||||
}
|
||||
|
||||
int final_sz = ((width() / sz) - 1) * sz;
|
||||
img = QPixmap::fromImage(im.scaled(final_sz, final_sz, Qt::KeepAspectRatio), Qt::MonoOnly);
|
||||
}
|
||||
|
||||
void SunnylinkCommunityQRWidget::paintEvent(QPaintEvent *e) {
|
||||
QPainter p(this);
|
||||
p.fillRect(rect(), Qt::white);
|
||||
|
||||
if (!img.isNull()) {
|
||||
QSize s = (size() - img.size()) / 2;
|
||||
p.drawPixmap(s.width(), s.height(), img);
|
||||
}
|
||||
}
|
||||
|
||||
// --- SunnylinkCommunityPopup ---
|
||||
|
||||
QStringList SunnylinkCommunityPopup::getInstructions() {
|
||||
QStringList instructions;
|
||||
instructions << tr("Scan the QR code and join us!");
|
||||
return instructions;
|
||||
}
|
||||
|
||||
SunnylinkCommunityPopup::SunnylinkCommunityPopup(QWidget* parent)
|
||||
: DialogBase(parent) {
|
||||
auto *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
|
||||
// Solarized Light base3 background
|
||||
setStyleSheet("SunnylinkCommunityPopup { background-color: #FDF6E3; }");
|
||||
|
||||
// Header spanning full width
|
||||
auto headerWidget = new QWidget(this);
|
||||
auto headerLayout = new QHBoxLayout(headerWidget);
|
||||
headerLayout->setContentsMargins(85, 50, 85, 30);
|
||||
headerLayout->setSpacing(30);
|
||||
|
||||
auto close = new QPushButton(QIcon(":/icons/close.svg"), "", this);
|
||||
close->setIconSize(QSize(80, 80));
|
||||
close->setStyleSheet("border: none;");
|
||||
connect(close, &QPushButton::clicked, this, &QDialog::reject);
|
||||
headerLayout->addWidget(close, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
const auto title = new QLabel(tr("Join the sunnypilot Community Forum"), this);
|
||||
// Solarized base02 for text
|
||||
title->setStyleSheet("font-size: 65px; color: #073642;");
|
||||
title->setWordWrap(false);
|
||||
title->setAlignment(Qt::AlignCenter);
|
||||
headerLayout->addWidget(title, 1);
|
||||
|
||||
// Spacer to balance the close button on the right
|
||||
auto spacer = new QWidget(this);
|
||||
spacer->setFixedSize(80, 80);
|
||||
headerLayout->addWidget(spacer, 0);
|
||||
|
||||
mainLayout->addWidget(headerWidget);
|
||||
|
||||
// Two-column content layout
|
||||
auto contentLayout = new QHBoxLayout();
|
||||
contentLayout->setContentsMargins(0, 0, 0, 0);
|
||||
contentLayout->setSpacing(0);
|
||||
mainLayout->addLayout(contentLayout, 66);
|
||||
|
||||
// Left side: description
|
||||
auto leftLayout = new QVBoxLayout();
|
||||
leftLayout->setContentsMargins(85, 40, 50, 70);
|
||||
leftLayout->setSpacing(35);
|
||||
contentLayout->addLayout(leftLayout, 40);
|
||||
|
||||
// Hype / intro paragraph
|
||||
const auto desc = new QLabel(tr(
|
||||
"We're excited to announce our <b>sunnypilot Community Forum</b><br><br>"
|
||||
"Over the years, Discord just hasn't scaled well for our growing community.<br>"
|
||||
"It's noisy, unsearchable, and great discussions disappear too easily.<br>"
|
||||
"Our new community forum aims to fix that by making it easier to <b>find answers, share ideas, track feedback, report bugs, help newcomers</b> and more!<br><br>"
|
||||
"<b>Here's what's waiting for you:</b><br>"
|
||||
"• Fully <b>indexable</b> and discoverable through search engines 🔎<br>"
|
||||
"• <b>AI-powered</b>🤖 topic and chat summaries, spam detection, and more<br>"
|
||||
"• A <b>trust-level system</b>✅ that rewards meaningful contributions<br>"
|
||||
"• Designed to work <b>on your own time</b>.🧘<br><br>"
|
||||
"Scan the QR code on the right and join the discussion!"
|
||||
), this);
|
||||
// Solarized base01 for body text
|
||||
desc->setStyleSheet("font-size: 40px; color: #586E75;");
|
||||
desc->setWordWrap(true);
|
||||
leftLayout->addWidget(desc);
|
||||
|
||||
leftLayout->addStretch();
|
||||
|
||||
// Right side: QR code and instructions
|
||||
auto rightLayout = new QVBoxLayout();
|
||||
rightLayout->setContentsMargins(50, 40, 85, 70);
|
||||
rightLayout->setSpacing(40);
|
||||
contentLayout->addLayout(rightLayout, 1);
|
||||
|
||||
// QR code (smaller, fixed size)
|
||||
auto *qr = new SunnylinkCommunityQRWidget(this);
|
||||
qr->setFixedSize(500, 500);
|
||||
rightLayout->addStretch();
|
||||
rightLayout->addWidget(qr, 0, Qt::AlignCenter);
|
||||
rightLayout->addStretch();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) 2025-, sunnypilot contributors.
|
||||
*
|
||||
* This file is part of sunnypilot and is licensed under the MIT License.
|
||||
* See the LICENSE.md file in the root directory for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QrCode.hpp>
|
||||
#include <QtCore/qjsonobject.h>
|
||||
|
||||
#include "common/util.h"
|
||||
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
|
||||
|
||||
const QString SUNNYLINK_COMMUNITY_URL = "https://community.sunnypilot.ai/sp-qr";
|
||||
|
||||
class SunnylinkCommunityQRWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SunnylinkCommunityQRWidget(QWidget* parent = nullptr);
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
|
||||
private:
|
||||
QPixmap img;
|
||||
void updateQrCode(const QString &text);
|
||||
void showEvent(QShowEvent *event) override;
|
||||
};
|
||||
|
||||
// Popup widget
|
||||
class SunnylinkCommunityPopup : public DialogBase {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SunnylinkCommunityPopup(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
static QStringList getInstructions();
|
||||
};
|
||||
@@ -79,11 +79,11 @@ QStringList SunnylinkSponsorPopup::getInstructions(bool sponsor_pair) {
|
||||
instructions << tr("Scan the QR code to login to your GitHub account")
|
||||
<< tr("Follow the prompts to complete the pairing process")
|
||||
<< tr("Re-enter the \"sunnylink\" panel to verify sponsorship status")
|
||||
<< tr("If sponsorship status was not updated, please contact a moderator on Discord at https://discord.gg/sunnypilot");
|
||||
<< tr("If sponsorship status was not updated, please contact a moderator on our forum at https://community.sunnypilot.ai");
|
||||
} else {
|
||||
instructions << tr("Scan the QR code to visit sunnyhaibin's GitHub Sponsors page")
|
||||
<< tr("Choose your sponsorship tier and confirm your support")
|
||||
<< tr("Join our community on Discord at https://discord.gg/sunnypilot and reach out to a moderator to confirm your sponsor status");
|
||||
<< tr("Join our Community Forum at https://community.sunnypilot.ai and reach out to a moderator if you have issues");
|
||||
}
|
||||
return instructions;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user