plugins: remove localmonero

Thank you Alex for all you've done for the community over the years.
This commit is contained in:
tobtoht 2024-05-07 21:30:37 +02:00
parent af9d9ddc21
commit 8d814a16b3
No known key found for this signature in database
GPG key ID: E45B10DD027D2472
31 changed files with 4 additions and 1668 deletions

View file

@ -34,8 +34,6 @@ option(WITH_PLUGIN_BOUNTIES "Include Bounties Home plugin" ON)
option(WITH_PLUGIN_REDDIT "Include Reddit Home plugin" ON)
option(WITH_PLUGIN_REVUO "Include Revuo Home plugin" ON)
option(WITH_PLUGIN_CALC "Include Calc tab plugin" ON)
option(WITH_PLUGIN_EXCHANGE "Include Exchange tab plugin" ON)
option(WITH_PLUGIN_LOCALMONERO "Include LocalMonero plugin" ON)
option(WITH_PLUGIN_XMRIG "Include XMRig plugin" ON)
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")

View file

@ -20,7 +20,7 @@ ContactsWidget::ContactsWidget(Wallet *wallet, QWidget *parent)
ui->setupUi(this);
m_btn_addContact = new QPushButton(this);
m_btn_addContact->setIcon(icons()->icon("localMonero_register.svg"));
m_btn_addContact->setIcon(icons()->icon("register.svg"));
ui->searchLayout->addWidget(m_btn_addContact, 0, Qt::AlignRight);
connect(m_btn_addContact, &QPushButton::clicked, [this]{this->newContact();});

View file

@ -359,19 +359,6 @@ void Settings::setupMiscTab() {
QString redditFrontend = ui->comboBox_redditFrontend->currentText();
conf()->set(Config::redditFrontend, redditFrontend);
});
// [LocalMonero frontend]
ui->comboBox_localMoneroFrontend->addItem("localmonero.co", "https://localmonero.co");
ui->comboBox_localMoneroFrontend->addItem("localmonero.co/nojs", "https://localmonero.co/nojs");
ui->comboBox_localMoneroFrontend->addItem("nehdddktmhvqklsnkjqcbpmb63htee2iznpcbs5tgzctipxykpj6yrid.onion",
"http://nehdddktmhvqklsnkjqcbpmb63htee2iznpcbs5tgzctipxykpj6yrid.onion");
ui->comboBox_localMoneroFrontend->addItem("yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q.b32.i2p",
"http://yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q.b32.i2p");
ui->comboBox_localMoneroFrontend->setCurrentIndex(ui->comboBox_localMoneroFrontend->findData(conf()->get(Config::localMoneroFrontend).toString()));
connect(ui->comboBox_localMoneroFrontend, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]{
QString localMoneroFrontend = ui->comboBox_localMoneroFrontend->currentData().toString();
conf()->set(Config::localMoneroFrontend, localMoneroFrontend);
});
}
void Settings::onProxySettingsChanged() {

View file

@ -32,7 +32,7 @@
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>5</number>
<number>0</number>
</property>
<widget class="QWidget" name="page_appearance">
<layout class="QVBoxLayout" name="verticalLayout_6">
@ -1109,22 +1109,6 @@
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_19">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>LocalMonero frontend:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_localMoneroFrontend"/>
</item>
<item>
<spacer name="verticalSpacer_7">
<property name="orientation">

View file

@ -50,13 +50,6 @@
<file>assets/images/ledger.png</file>
<file>assets/images/ledger_unpaired.png</file>
<file>assets/images/lightning.png</file>
<file>assets/images/localMonero_search.svg</file>
<file>assets/images/localMonero_buy.svg</file>
<file>assets/images/localMonero_buy_white.svg</file>
<file>assets/images/localMonero_sell.svg</file>
<file>assets/images/localMonero_sell_white.svg</file>
<file>assets/images/localMonero_logo.png</file>
<file>assets/images/localMonero_register.svg</file>
<file>assets/images/lock.svg</file>
<file>assets/images/microphone.png</file>
<file>assets/images/mining.png</file>
@ -70,6 +63,7 @@
<file>assets/images/preferences.svg</file>
<file>assets/images/qrcode.png</file>
<file>assets/images/qrcode_white.png</file>
<file>assets/images/register.svg</file>
<file>assets/images/revealer_c.png</file>
<file>assets/images/revealer.png</file>
<file>assets/images/seal.png</file>

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="MuiSvgIcon-root" focusable="false" viewBox="0 0 24 24" aria-hidden="true" style="margin-right: 8px;"><path d="M10,0V4H8L12,8L16,4H14V0M1,2V4H3L6.6,11.59L5.25,14.04C5.09,14.32 5,14.65 5,15A2,2 0 0,0 7,17H19V15H7.42C7.29,15 7.17,14.89 7.17,14.75L7.2,14.63L8.1,13H15.55C16.3,13 16.96,12.59 17.3,11.97L21.16,4.96L19.42,4H19.41L18.31,6L15.55,11H8.53L8.4,10.73L6.16,6L5.21,4L4.27,2M7,18A2,2 0 0,0 5,20A2,2 0 0,0 7,22A2,2 0 0,0 9,20A2,2 0 0,0 7,18M17,18A2,2 0 0,0 15,20A2,2 0 0,0 17,22A2,2 0 0,0 19,20A2,2 0 0,0 17,18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 574 B

View file

@ -1 +0,0 @@
<svg fill="#FFFFFF" xmlns="http://www.w3.org/2000/svg" class="MuiSvgIcon-root" focusable="false" viewBox="0 0 24 24" aria-hidden="true" style="margin-right: 8px;"><path d="M10,0V4H8L12,8L16,4H14V0M1,2V4H3L6.6,11.59L5.25,14.04C5.09,14.32 5,14.65 5,15A2,2 0 0,0 7,17H19V15H7.42C7.29,15 7.17,14.89 7.17,14.75L7.2,14.63L8.1,13H15.55C16.3,13 16.96,12.59 17.3,11.97L21.16,4.96L19.42,4H19.41L18.31,6L15.55,11H8.53L8.4,10.73L6.16,6L5.21,4L4.27,2M7,18A2,2 0 0,0 5,20A2,2 0 0,0 7,22A2,2 0 0,0 9,20A2,2 0 0,0 7,18M17,18A2,2 0 0,0 15,20A2,2 0 0,0 17,22A2,2 0 0,0 19,20A2,2 0 0,0 17,18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="MuiSvgIcon-root-6593" focusable="false" viewBox="0 0 24 24" aria-hidden="true" style="margin-right: 8px;"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></svg>

Before

Width:  |  Height:  |  Size: 412 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="MuiSvgIcon-root" focusable="false" viewBox="0 0 24 24" aria-hidden="true" style="margin-right: 8px;"><path d="M12,0L8,4H10V8H14V4H16M1,2V4H3L6.6,11.59L5.25,14.04C5.09,14.32 5,14.65 5,15A2,2 0 0,0 7,17H19V15H7.42C7.29,15 7.17,14.89 7.17,14.75L7.2,14.63L8.1,13H15.55C16.3,13 16.96,12.59 17.3,11.97L21.16,4.96L19.42,4H19.41L18.31,6L15.55,11H8.53L8.4,10.73L6.16,6L5.21,4L4.27,2M7,18A2,2 0 0,0 5,20A2,2 0 0,0 7,22A2,2 0 0,0 9,20A2,2 0 0,0 7,18M17,18A2,2 0 0,0 15,20A2,2 0 0,0 17,22A2,2 0 0,0 19,20A2,2 0 0,0 17,18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 572 B

View file

@ -1 +0,0 @@
<svg fill="#FFFFFF" xmlns="http://www.w3.org/2000/svg" class="MuiSvgIcon-root" focusable="false" viewBox="0 0 24 24" aria-hidden="true" style="margin-right: 8px;"><path d="M12,0L8,4H10V8H14V4H16M1,2V4H3L6.6,11.59L5.25,14.04C5.09,14.32 5,14.65 5,15A2,2 0 0,0 7,17H19V15H7.42C7.29,15 7.17,14.89 7.17,14.75L7.2,14.63L8.1,13H15.55C16.3,13 16.96,12.59 17.3,11.97L21.16,4.96L19.42,4H19.41L18.31,6L15.55,11H8.53L8.4,10.73L6.16,6L5.21,4L4.27,2M7,18A2,2 0 0,0 5,20A2,2 0 0,0 7,22A2,2 0 0,0 9,20A2,2 0 0,0 7,18M17,18A2,2 0 0,0 15,20A2,2 0 0,0 17,22A2,2 0 0,0 19,20A2,2 0 0,0 17,18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 587 B

View file

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View file

@ -1,64 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "ExchangePlugin.h"
#include "plugins/PluginRegistry.h"
ExchangePlugin::ExchangePlugin()
{
}
void ExchangePlugin::initialize(Wallet *wallet, QObject *parent) {
this->setParent(parent);
m_tab = new ExchangeWidget(nullptr);
}
QString ExchangePlugin::id() {
return "exchange";
}
int ExchangePlugin::idx() const {
return 50;
}
QString ExchangePlugin::parent() {
return "";
}
QString ExchangePlugin::displayName() {
return "Exchange";
}
QString ExchangePlugin::description() {
return {};
}
QString ExchangePlugin::icon() {
return "update.png";
}
QStringList ExchangePlugin::socketData() {
return {};
}
Plugin::PluginType ExchangePlugin::type() {
return Plugin::PluginType::TAB;
}
QWidget* ExchangePlugin::tab() {
return m_tab;
}
void ExchangePlugin::addSubPlugin(Plugin* plugin) {
m_tab->addTab(plugin);
}
bool ExchangePlugin::implicitEnable() {
return true;
}
const bool ExchangePlugin::registered = [] {
PluginRegistry::registerPlugin(ExchangePlugin::create());
PluginRegistry::getInstance().registerPluginCreator(&ExchangePlugin::create);
return true;
}();

View file

@ -1,38 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#ifndef EXCHANGEPLUGIN_H
#define EXCHANGEPLUGIN_H
#include "plugins/Plugin.h"
#include "ExchangeWidget.h"
class ExchangePlugin : public Plugin {
Q_OBJECT
public:
explicit ExchangePlugin();
QString id() override;
int idx() const override;
QString parent() override;
QString displayName() override;
QString description() override;
QString icon() override;
QStringList socketData() override;
PluginType type() override;
QWidget* tab() override;
bool implicitEnable() override;
void addSubPlugin(Plugin* plugin) override;
void initialize(Wallet *wallet, QObject *parent) override;
static ExchangePlugin* create() { return new ExchangePlugin(); }
private:
ExchangeWidget* m_tab = nullptr;
static const bool registered;
};
#endif //EXCHANGEPLUGIN_H

View file

@ -1,24 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "ExchangeWidget.h"
#include "ui_ExchangeWidget.h"
#include "utils/Icons.h"
ExchangeWidget::ExchangeWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::ExchangeWidget)
{
ui->setupUi(this);
}
void ExchangeWidget::addTab(Plugin *plugin) {
QWidget* tab = plugin->tab();
auto icon = icons()->icon(plugin->icon());
QString name = plugin->displayName();
ui->tabWidget->addTab(tab, icon, name);
}
ExchangeWidget::~ExchangeWidget() = default;

View file

@ -1,31 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#ifndef EXCHANGEWIDGET_H
#define EXCHANGEWIDGET_H
#include <QWidget>
#include <QTabWidget>
#include "plugins/Plugin.h"
namespace Ui {
class ExchangeWidget;
}
class ExchangeWidget : public QWidget
{
Q_OBJECT
public:
explicit ExchangeWidget(QWidget *parent = nullptr);
~ExchangeWidget();
void addTab(Plugin *plugin);
private:
QScopedPointer<Ui::ExchangeWidget> ui;
};
#endif //EXCHANGEWIDGET_H

View file

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExchangeWidget</class>
<widget class="QWidget" name="ExchangeWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -1,119 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "LocalMoneroApi.h"
#include "utils/config.h"
LocalMoneroApi::LocalMoneroApi(QObject *parent, Networking *network)
: QObject(parent)
, m_network(network)
{
}
void LocalMoneroApi::countryCodes() {
QString url = QString("%1/countrycodes").arg(this->getBaseUrl());
QNetworkReply *reply = m_network->getJson(this, url);
connect(reply, &QNetworkReply::finished, std::bind(&LocalMoneroApi::onResponse, this, reply, Endpoint::COUNTRY_CODES));
}
void LocalMoneroApi::currencies() {
QString url = QString("%1/currencies").arg(this->getBaseUrl());
QNetworkReply *reply = m_network->getJson(this, url);
connect(reply, &QNetworkReply::finished, std::bind(&LocalMoneroApi::onResponse, this, reply, Endpoint::CURRENCIES));
}
void LocalMoneroApi::paymentMethods(const QString &countryCode) {
QString url;
if (countryCode.isEmpty()) {
url = QString("%1/payment_methods").arg(this->getBaseUrl());
} else {
url = QString("%1/payment_methods/%2").arg(this->getBaseUrl(), countryCode);
}
QNetworkReply *reply = m_network->getJson(this, url);
connect(reply, &QNetworkReply::finished, std::bind(&LocalMoneroApi::onResponse, this, reply, Endpoint::PAYMENT_METHODS));
}
void LocalMoneroApi::buyMoneroOnline(const QString &currencyCode, const QString &countryCode,
const QString &paymentMethod, const QString &amount, int page)
{
QString url = this->getBuySellUrl(true, currencyCode, countryCode, paymentMethod, amount, page);
QNetworkReply *reply = m_network->getJson(this, url);
connect(reply, &QNetworkReply::finished, std::bind(&LocalMoneroApi::onResponse, this, reply, Endpoint::BUY_MONERO_ONLINE));
}
void LocalMoneroApi::sellMoneroOnline(const QString &currencyCode, const QString &countryCode,
const QString &paymentMethod, const QString &amount, int page)
{
QString url = this->getBuySellUrl(false, currencyCode, countryCode, paymentMethod, amount, page);
QNetworkReply *reply = m_network->getJson(this, url);
connect(reply, &QNetworkReply::finished, std::bind(&LocalMoneroApi::onResponse, this, reply, Endpoint::SELL_MONERO_ONLINE));
}
void LocalMoneroApi::accountInfo(const QString &username) {
QString url = QString("%1/account_info/%2").arg(this->getBaseUrl(), username);
QNetworkReply *reply = m_network->getJson(this, url);
connect(reply, &QNetworkReply::finished, std::bind(&LocalMoneroApi::onResponse, this, reply, Endpoint::ACCOUNT_INFO));
}
void LocalMoneroApi::onResponse(QNetworkReply *reply, LocalMoneroApi::Endpoint endpoint) {
const bool ok = reply->error() == QNetworkReply::NoError;
const QString err = reply->errorString();
QByteArray data = reply->readAll();
reply->deleteLater();
QJsonObject obj;
if (!data.isEmpty() && Utils::validateJSON(data)) {
auto doc = QJsonDocument::fromJson(data);
obj = doc.object();
}
else if (!ok) {
emit ApiResponse(LocalMoneroResponse{false, endpoint, err, {}});
return;
}
else {
emit ApiResponse(LocalMoneroResponse{false, endpoint, "Invalid response from LocalMonero", {}});
return;
}
if (obj.contains("error")) {
QString errorStr = QJsonDocument(obj["error"].toObject()).toJson(QJsonDocument::Compact);
emit ApiResponse(LocalMoneroResponse{false, endpoint, errorStr, obj});
return;
}
emit ApiResponse(LocalMoneroResponse{true, endpoint, "", obj});
}
QString LocalMoneroApi::getBuySellUrl(bool buy, const QString &currencyCode, const QString &countryCode,
const QString &paymentMethod, const QString &amount, int page)
{
QString url = QString("%1/%2-monero-online/%3").arg(this->getBaseUrl(), buy ? "buy" : "sell", currencyCode);
if (!countryCode.isEmpty() && paymentMethod.isEmpty())
url += QString("/%1").arg(countryCode);
else if (countryCode.isEmpty() && !paymentMethod.isEmpty())
url += QString("/%1").arg(paymentMethod);
else if (!countryCode.isEmpty() && !paymentMethod.isEmpty())
url += QString("/%1/%2").arg(countryCode, paymentMethod);
QUrlQuery query;
if (!amount.isEmpty() && amount != "0")
query.addQueryItem("amount", amount);
if (page > 0)
query.addQueryItem("page", QString::number(page));
url += "?" + query.toString();
return url;
}
QString LocalMoneroApi::getBaseUrl() {
if (conf()->get(Config::proxy).toInt() == Config::Proxy::Tor && conf()->get(Config::torOnlyAllowOnion).toBool()) {
return "http://nehdddktmhvqklsnkjqcbpmb63htee2iznpcbs5tgzctipxykpj6yrid.onion/api/v1";
}
if (conf()->get(Config::proxy).toInt() == Config::Proxy::i2p) {
return "http://yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q.b32.i2p/api/v1";
}
return "https://agoradesk.com/api/v1";
}

View file

@ -1,53 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#ifndef FEATHER_LOCALMONEROAPI_H
#define FEATHER_LOCALMONEROAPI_H
#include <QObject>
#include "utils/Networking.h"
class LocalMoneroApi : public QObject {
Q_OBJECT
public:
enum Endpoint {
COUNTRY_CODES,
CURRENCIES,
PAYMENT_METHODS,
BUY_MONERO_ONLINE,
SELL_MONERO_ONLINE,
ACCOUNT_INFO
};
struct LocalMoneroResponse {
bool ok;
Endpoint endpoint;
QString message;
QJsonObject obj;
};
explicit LocalMoneroApi(QObject *parent, Networking *network);
void countryCodes();
void currencies();
void paymentMethods(const QString &countryCode = "");
void buyMoneroOnline(const QString &currencyCode, const QString &countryCode="", const QString &paymentMethod="", const QString &amount = "", int page = 0);
void sellMoneroOnline(const QString &currencyCode, const QString &countryCode="", const QString &paymentMethod="", const QString &amount = "", int page = 0);
void accountInfo(const QString &username);
signals:
void ApiResponse(LocalMoneroResponse resp);
private slots:
void onResponse(QNetworkReply *reply, Endpoint endpoint);
private:
QString getBuySellUrl(bool buy, const QString &currencyCode, const QString &countryCode="", const QString &paymentMethod="", const QString &amount = "", int page = 0);
QString getBaseUrl();
Networking *m_network;
};
#endif //FEATHER_LOCALMONEROAPI_H

View file

@ -1,49 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "LocalMoneroInfoDialog.h"
#include "ui_LocalMoneroInfoDialog.h"
#include "utils/config.h"
#include "utils/Utils.h"
LocalMoneroInfoDialog::LocalMoneroInfoDialog(QWidget *parent, LocalMoneroModel *model, int row)
: WindowModalDialog(parent)
, ui(new Ui::LocalMoneroInfoDialog)
, m_model(model)
, m_row(row)
{
ui->setupUi(this);
setLabelText(ui->label_price, LocalMoneroModel::PriceXMR);
setLabelText(ui->label_seller, LocalMoneroModel::Seller);
setLabelText(ui->label_paymentMethod, LocalMoneroModel::PaymentMethod);
setLabelText(ui->label_paymentDetail, LocalMoneroModel::PaymentMethodDetail);
setLabelText(ui->label_tradeLimits, LocalMoneroModel::Limits);
QJsonObject offerData = model->getOffer(row);
QString details = offerData["data"].toObject()["msg"].toString();
details.remove("*");
if (details.isEmpty()) {
details = "No details.";
}
ui->info->setPlainText(details);
connect(ui->btn_goToOffer, &QPushButton::clicked, this, &LocalMoneroInfoDialog::onGoToOffer);
}
void LocalMoneroInfoDialog::setLabelText(QLabel *label, LocalMoneroModel::Column column) {
QString data = m_model->data(m_model->index(m_row, column)).toString();
label->setText(data);
}
void LocalMoneroInfoDialog::onGoToOffer() {
QJsonObject offerData = m_model->getOffer(m_row);
QString frontend = conf()->get(Config::localMoneroFrontend).toString();
QString offerUrl = QString("%1/ad/%2").arg(frontend, offerData["data"].toObject()["ad_id"].toString());
Utils::externalLinkWarning(this, offerUrl);
}
LocalMoneroInfoDialog::~LocalMoneroInfoDialog() = default;

View file

@ -1,37 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#ifndef FEATHER_LOCALMONEROINFODIALOG_H
#define FEATHER_LOCALMONEROINFODIALOG_H
#include <QDialog>
#include <QLabel>
#include "components.h"
#include "LocalMoneroModel.h"
namespace Ui {
class LocalMoneroInfoDialog;
}
class LocalMoneroInfoDialog : public WindowModalDialog
{
Q_OBJECT
public:
explicit LocalMoneroInfoDialog(QWidget *parent, LocalMoneroModel *model, int row);
~LocalMoneroInfoDialog() override;
private slots:
void onGoToOffer();
private:
void setLabelText(QLabel *label, LocalMoneroModel::Column column);
QScopedPointer<Ui::LocalMoneroInfoDialog> ui;
LocalMoneroModel *m_model;
int m_row;
};
#endif //FEATHER_INFODIALOG_H

View file

@ -1,195 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LocalMoneroInfoDialog</class>
<widget class="QDialog" name="LocalMoneroInfoDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>758</width>
<height>557</height>
</rect>
</property>
<property name="windowTitle">
<string>Offer info</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Info</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Price:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_price">
<property name="text">
<string>TextLabel</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Seller:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_seller">
<property name="text">
<string>TextLabel</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Payment method:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_paymentMethod">
<property name="text">
<string>TextLabel</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Trade limits:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_tradeLimits">
<property name="text">
<string>TextLabel</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Payment detail:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_paymentDetail">
<property name="text">
<string>TextLabel</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="info">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_goToOffer">
<property name="text">
<string>Go to offer</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>LocalMoneroInfoDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>LocalMoneroInfoDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -1,172 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "LocalMoneroModel.h"
#include <QColor>
#include "utils/Utils.h"
LocalMoneroModel::LocalMoneroModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
int LocalMoneroModel::rowCount(const QModelIndex &parent) const {
return m_data.count();
}
int LocalMoneroModel::columnCount(const QModelIndex &parent) const {
return Column::COUNT;
}
QVariant LocalMoneroModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
switch (section) {
case Seller:
return QString("Seller");
case Country:
return QString("Country");
case PaymentMethod:
return QString("Payment Method");
case PaymentMethodDetail:
return QString("Detail");
case PriceXMR:
return QString("Price/XMR");
case Limits:
return QString("Limits");
default:
return QVariant();
}
}
return QVariant();
}
QVariant LocalMoneroModel::data(const QModelIndex &index, int role) const {
const int col = index.column();
const auto row = m_data.at(index.row()).toObject()["data"].toObject();
if (row.isEmpty()) {
return QVariant();
}
if (role == Qt::DisplayRole) {
switch (col) {
case Column::Seller: {
auto seller = row["profile"].toObject();
return seller["name"].toString();
// TODO: online indicator
}
case Column::Country: {
return row["countrycode"].toString();
}
case Column::PaymentMethod: {
auto paymentMethodCode = row["online_provider"].toString();
if (paymentMethodCode == "NATIONAL_BANK") {
return QString("National bank transfer");
}
return m_paymentMethodNames.value(paymentMethodCode, paymentMethodCode);
}
case Column::PaymentMethodDetail: {
auto paymentMethodDetailText = row["payment_method_detail"].toString();
QString filteredString; // We can't display emojis in QTreeView
for (const auto &Char : paymentMethodDetailText) {
if (Char.unicode() < 256)
filteredString.append(Char);
else
filteredString.append(" ");
}
return filteredString.trimmed();
}
case Column::PriceXMR: {
return QString("%1 %2").arg(row["temp_price"].toString(), row["currency"].toString());
}
case Column::Limits: {
auto minAmount = row["min_amount"].toString();
auto maxAmount = row["max_amount"].toString();
if (maxAmount.isEmpty()) {
maxAmount = row["max_amount_available"].toString();
}
auto currency = row["currency"].toString();
if (minAmount.isEmpty() && maxAmount.isEmpty()) {
return QString("Up to any amount %1").arg(currency);
}
if (!minAmount.isEmpty() && maxAmount.isEmpty()) {
return QString("%1 - any amount %2").arg(minAmount, currency);
}
if (!minAmount.isEmpty() && !maxAmount.isEmpty()) {
return QString("%1 - %2 %3").arg(minAmount, maxAmount, currency);
}
if (minAmount.isEmpty() && !maxAmount.isEmpty()) {
return QString("Up to %1 %2").arg(maxAmount, currency);
}
return QVariant();
}
}
}
else if (role == Qt::ForegroundRole) {
switch (col) {
case Column::PriceXMR: {
return QVariant(QColor("#388538"));
}
}
}
else if (role == Qt::FontRole) {
switch (col) {
case Column::PriceXMR: {
auto bigFont = Utils::relativeFont(2);
bigFont.setBold(true);
return bigFont;
}
}
}
return QVariant();
}
void LocalMoneroModel::setData(const QJsonArray &data) {
beginResetModel();
m_data = data;
endResetModel();
}
void LocalMoneroModel::addData(const QJsonArray &data) {
beginResetModel();
for (const auto &row : data) {
m_data.append(row);
}
endResetModel();
}
void LocalMoneroModel::clearData() {
beginResetModel();
m_data = {};
endResetModel();
}
void LocalMoneroModel::setPaymentMethods(const QJsonObject &data) {
beginResetModel();
m_paymentMethods = data;
m_paymentMethodNames.clear();
for (const auto &payment_method : data) {
auto code = payment_method.toObject()["code"].toString();
auto name = payment_method.toObject()["name"].toString();
if (!code.isEmpty() && !name.isEmpty()) {
m_paymentMethodNames[code] = name;
}
}
endResetModel();
}
QJsonObject LocalMoneroModel::getOffer(int index) const {
return m_data.at(index).toObject();
}

View file

@ -1,47 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#ifndef FEATHER_LOCALMONEROMODEL_H
#define FEATHER_LOCALMONEROMODEL_H
#include <QAbstractTableModel>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
class LocalMoneroModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum Column
{
Seller = 0,
Country,
PaymentMethod,
PaymentMethodDetail,
PriceXMR,
Limits,
COUNT
};
LocalMoneroModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void setData(const QJsonArray &data);
void setPaymentMethods(const QJsonObject &data);
void addData(const QJsonArray &data);
void clearData();
QJsonObject getOffer(int index) const;
private:
QJsonArray m_data;
QJsonObject m_paymentMethods;
QHash<QString, QString> m_paymentMethodNames;
};
#endif //FEATHER_LOCALMONEROMODEL_H

View file

@ -1,58 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "LocalMoneroPlugin.h"
LocalMoneroPlugin::LocalMoneroPlugin()
{
}
void LocalMoneroPlugin::initialize(Wallet *wallet, QObject *parent) {
this->setParent(parent);
m_tab = new LocalMoneroWidget(nullptr, wallet);
}
QString LocalMoneroPlugin::id() {
return "localmonero";
}
int LocalMoneroPlugin::idx() const {
return 0;
}
QString LocalMoneroPlugin::parent() {
return "exchange";
}
QString LocalMoneroPlugin::displayName() {
return "LocalMonero";
}
QString LocalMoneroPlugin::description() {
return {};
}
QString LocalMoneroPlugin::icon() {
return "localMonero_logo.png";
}
QStringList LocalMoneroPlugin::socketData() {
return {"localmonero_countries", "localmonero_currencies", "localmonero_payment_methods"};
}
Plugin::PluginType LocalMoneroPlugin::type() {
return Plugin::PluginType::TAB;
}
QWidget* LocalMoneroPlugin::tab() {
return m_tab;
}
void LocalMoneroPlugin::skinChanged() {
m_tab->skinChanged();
}
const bool LocalMoneroPlugin::registered = [] {
PluginRegistry::registerPlugin(LocalMoneroPlugin::create());
PluginRegistry::getInstance().registerPluginCreator(&LocalMoneroPlugin::create);
return true;
}();

View file

@ -1,40 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#ifndef LOCALMONEROPLUGIN_H
#define LOCALMONEROPLUGIN_H
#include "plugins/Plugin.h"
#include "LocalMoneroWidget.h"
#include "plugins/PluginRegistry.h"
class LocalMoneroPlugin : public Plugin {
Q_OBJECT
public:
explicit LocalMoneroPlugin();
QString id() override;
int idx() const override;
QString parent() override;
QString displayName() override;
QString description() override;
QString icon() override;
QStringList socketData() override;
PluginType type() override;
QWidget* tab() override;
void initialize(Wallet *wallet, QObject *parent) override;
static LocalMoneroPlugin* create() { return new LocalMoneroPlugin(); }
public slots:
void skinChanged() override;
private:
LocalMoneroWidget* m_tab = nullptr;
static const bool registered;
};
#endif //LOCALMONEROPLUGIN_H

View file

@ -1,216 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "LocalMoneroWidget.h"
#include "ui_LocalMoneroWidget.h"
#include <QMessageBox>
#include <QMenu>
#include "LocalMoneroInfoDialog.h"
#include "utils/ColorScheme.h"
#include "utils/Icons.h"
#include "utils/WebsocketNotifier.h"
LocalMoneroWidget::LocalMoneroWidget(QWidget *parent, Wallet *wallet)
: QWidget(parent)
, ui(new Ui::LocalMoneroWidget)
, m_wallet(wallet)
{
ui->setupUi(this);
QPixmap logo(":/assets/images/localMonero_logo.png");
ui->logo->setPixmap(logo.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->combo_currency->addItem(conf()->get(Config::preferredFiatCurrency).toString());
m_network = new Networking(this);
m_api = new LocalMoneroApi(this, m_network);
m_model = new LocalMoneroModel(this);
ui->treeView->setModel(m_model);
ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->treeView->header()->setSectionResizeMode(LocalMoneroModel::PaymentMethodDetail, QHeaderView::Stretch);
ui->treeView->header()->setStretchLastSection(false);
connect(ui->treeView, &QTreeView::doubleClicked, this, &LocalMoneroWidget::viewOfferDetails);
connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &LocalMoneroWidget::showContextMenu);
connect(ui->btn_search, &QPushButton::clicked, this, &LocalMoneroWidget::onSearchClicked);
connect(ui->btn_signUp, &QPushButton::clicked, this, &LocalMoneroWidget::onSignUpClicked);
connect(m_api, &LocalMoneroApi::ApiResponse, this, &LocalMoneroWidget::onApiResponse);
connect(ui->btn_loadMore, &QPushButton::clicked, this, &LocalMoneroWidget::onLoadMore);
connect(websocketNotifier(), &WebsocketNotifier::dataReceived, this, [this](const QString& type, const QJsonValue& json) {
if (type == "localmonero_countries") {
this->onWsCountriesReceived(json.toArray());
}
else if (type == "localmonero_currencies") {
this->onWsCurrenciesReceived(json.toArray());
}
else if (type == "localmonero_payment_methods") {
this->onWsPaymentMethodsReceived(json.toObject());
}
});
connect(ui->combo_currency, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LocalMoneroWidget::updatePaymentMethods);
ui->frame_loadMore->hide();
QTimer::singleShot(1, [this]{
this->skinChanged();
});
}
void LocalMoneroWidget::skinChanged() {
if (ColorScheme::hasDarkBackground(this)) {
ui->radio_buy->setIcon(icons()->icon("localMonero_buy_white.svg"));
ui->radio_sell->setIcon(icons()->icon("localMonero_sell_white.svg"));
} else {
ui->radio_buy->setIcon(icons()->icon("localMonero_buy.svg"));
ui->radio_sell->setIcon(icons()->icon("localMonero_sell.svg"));
}
}
void LocalMoneroWidget::onSearchClicked() {
m_model->clearData();
m_currentPage = 0;
ui->btn_search->setEnabled(false);
this->searchOffers();
}
void LocalMoneroWidget::onSignUpClicked() {
QString signupUrl = QString("%1/signup").arg(conf()->get(Config::localMoneroFrontend).toString());
Utils::externalLinkWarning(this, signupUrl);
}
void LocalMoneroWidget::onApiResponse(const LocalMoneroApi::LocalMoneroResponse &resp) {
ui->btn_search->setEnabled(true);
if (!resp.ok) {
Utils::showError(this, "LocalMonero request failed", resp.message);
return;
}
if (resp.endpoint == LocalMoneroApi::BUY_MONERO_ONLINE
|| resp.endpoint == LocalMoneroApi::SELL_MONERO_ONLINE)
{
bool hasNextPage = resp.obj["pagination"].toObject().contains("next");
ui->frame_loadMore->setVisible(hasNextPage);
m_model->addData(resp.obj["data"].toObject()["ad_list"].toArray());
}
else if (resp.endpoint == LocalMoneroApi::PAYMENT_METHODS) {
m_model->setPaymentMethods(resp.obj["data"].toObject()["methods"].toObject());
}
}
void LocalMoneroWidget::onLoadMore() {
m_currentPage += 1;
this->searchOffers(m_currentPage);
}
void LocalMoneroWidget::onWsCountriesReceived(const QJsonArray &countries) {
ui->combo_country->clear();
ui->combo_country->addItem("Any country");
for (const auto country : countries) {
ui->combo_country->addItem(country[0].toString(), country[1].toString());
}
}
void LocalMoneroWidget::onWsCurrenciesReceived(const QJsonArray &currencies) {
QString currentText = ui->combo_currency->currentText();
ui->combo_currency->clear();
for (const auto currency : currencies) {
ui->combo_currency->addItem(currency.toString());
}
// restore previous selection
int index = ui->combo_currency->findText(currentText);
ui->combo_currency->setCurrentIndex(index);
}
void LocalMoneroWidget::onWsPaymentMethodsReceived(const QJsonObject &payment_methods) {
m_paymentMethods = payment_methods;
m_model->setPaymentMethods(payment_methods);
this->updatePaymentMethods();
}
void LocalMoneroWidget::searchOffers(int page) {
QString amount = ui->line_amount->text();
QString currencyCode = ui->combo_currency->currentText();
QString countryCode = ui->combo_country->currentData().toString();
QString paymentMethod = ui->combo_paymentMethod->currentData().toString();
if (ui->radio_buy->isChecked())
m_api->buyMoneroOnline(currencyCode, countryCode, paymentMethod, amount, page);
else if (ui->radio_sell->isChecked())
m_api->sellMoneroOnline(currencyCode, countryCode, paymentMethod, amount, page);
}
void LocalMoneroWidget::showContextMenu(const QPoint &point) {
QModelIndex index = ui->treeView->indexAt(point);
if (!index.isValid()) {
return;
}
QMenu menu(this);
menu.addAction("Go to offer", this, &LocalMoneroWidget::openOfferUrl);
menu.addAction("View offer details", this, &LocalMoneroWidget::viewOfferDetails);
menu.exec(ui->treeView->viewport()->mapToGlobal(point));
}
void LocalMoneroWidget::openOfferUrl() {
QModelIndex index = ui->treeView->currentIndex();
if (!index.isValid()) {
return;
}
QJsonObject offerData = m_model->getOffer(index.row());
QString frontend = conf()->get(Config::localMoneroFrontend).toString();
QString offerUrl = QString("%1/ad/%2").arg(frontend, offerData["data"].toObject()["ad_id"].toString());
Utils::externalLinkWarning(this, offerUrl);
}
void LocalMoneroWidget::viewOfferDetails() {
QModelIndex index = ui->treeView->currentIndex();
if (!index.isValid()) {
return;
}
QJsonObject offerData = m_model->getOffer(index.row());
QString details = offerData["data"].toObject()["msg"].toString();
details.remove("*");
if (details.isEmpty()) {
details = "No details.";
}
LocalMoneroInfoDialog dialog(this, m_model, index.row());
dialog.exec();
}
void LocalMoneroWidget::updatePaymentMethods() {
QString currency = ui->combo_currency->currentText().toUpper();
ui->combo_paymentMethod->clear();
ui->combo_paymentMethod->addItem("Any payment method");
for (const auto &payment_method : m_paymentMethods.keys()) {
auto pm = m_paymentMethods[payment_method].toObject();
if (pm["currencies"].toArray().contains(currency)) {
QString name = pm["name"].toString();
if (name.isEmpty())
name = payment_method;
ui->combo_paymentMethod->addItem(name, payment_method);
}
}
}
LocalMoneroWidget::~LocalMoneroWidget() = default;

View file

@ -1,56 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#ifndef FEATHER_LOCALMONEROWIDGET_H
#define FEATHER_LOCALMONEROWIDGET_H
#include <QWidget>
#include "LocalMoneroApi.h"
#include "LocalMoneroModel.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class LocalMoneroWidget;
}
class LocalMoneroWidget : public QWidget
{
Q_OBJECT
public:
explicit LocalMoneroWidget(QWidget *parent, Wallet *wallet);
~LocalMoneroWidget() override;
public slots:
void skinChanged();
private slots:
void onSearchClicked();
void onSignUpClicked();
void onApiResponse(const LocalMoneroApi::LocalMoneroResponse &resp);
void onLoadMore();
void onWsCountriesReceived(const QJsonArray &countries);
void onWsCurrenciesReceived(const QJsonArray &currencies);
void onWsPaymentMethodsReceived(const QJsonObject &payment_methods);
private:
void searchOffers(int page = 0);
void showContextMenu(const QPoint &point);
void openOfferUrl();
void viewOfferDetails();
void updatePaymentMethods();
QScopedPointer<Ui::LocalMoneroWidget> ui;
Wallet *m_wallet;
int m_currentPage = 0;
LocalMoneroApi *m_api;
LocalMoneroModel *m_model;
Networking *m_network;
QJsonObject m_paymentMethods;
};
#endif //FEATHER_LOCALMONEROWIDGET_H

View file

@ -1,385 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LocalMoneroWidget</class>
<widget class="QWidget" name="LocalMoneroWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1003</width>
<height>607</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_2"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="logo">
<property name="text">
<string>logo</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>LocalMonero.co</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QComboBox" name="combo_paymentMethod">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>Any payment method</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="line_amount">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>Amount</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="combo_currency">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="radio_sell">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Sell XMR</string>
</property>
<property name="icon">
<iconset resource="../assets.qrc">
<normaloff>:/assets/images/localMonero_sell_white.svg</normaloff>:/assets/images/localMonero_sell_white.svg</iconset>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QPushButton" name="btn_search">
<property name="text">
<string>Search</string>
</property>
<property name="icon">
<iconset resource="../assets.qrc">
<normaloff>:/assets/images/localMonero_search.svg</normaloff>:/assets/images/localMonero_search.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="radio_buy">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Buy XMR</string>
</property>
<property name="icon">
<iconset resource="../assets.qrc">
<normaloff>:/assets/images/localMonero_buy_white.svg</normaloff>:/assets/images/localMonero_buy_white.svg</iconset>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QComboBox" name="combo_country">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>Any country</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Buy Monero.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Sell Monero.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Cash or online.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Anywhere.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_signUp">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Sign up free</string>
</property>
<property name="icon">
<iconset resource="../assets.qrc">
<normaloff>:/assets/images/localMonero_register.svg</normaloff>:/assets/images/localMonero_register.svg</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="treeView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_loadMore">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_loadMore">
<property name="text">
<string>Load more</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>radio_buy</tabstop>
<tabstop>radio_sell</tabstop>
<tabstop>line_amount</tabstop>
<tabstop>combo_currency</tabstop>
<tabstop>combo_country</tabstop>
<tabstop>combo_paymentMethod</tabstop>
<tabstop>btn_search</tabstop>
<tabstop>btn_signUp</tabstop>
<tabstop>btn_loadMore</tabstop>
<tabstop>treeView</tabstop>
</tabstops>
<resources>
<include location="../assets.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -105,7 +105,6 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
"http://127.0.0.1:31312/tx?id=%txid%"}}},
{Config::blockExplorer,{QS("blockExplorer"), "https://xmrchain.net/tx/%txid%"}},
{Config::redditFrontend, {QS("redditFrontend"), "old.reddit.com"}},
{Config::localMoneroFrontend, {QS("localMoneroFrontend"), "https://localmonero.co"}},
{Config::bountiesFrontend, {QS("bountiesFrontend"), "https://bounties.monero.social"}},
{Config::lastPath, {QS("lastPath"), QDir::homePath()}},
@ -131,7 +130,7 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::useLocalTor, {QS("useLocalTor"), false}},
{Config::initSyncThreshold, {QS("initSyncThreshold"), 360}},
{Config::enabledPlugins, {QS("enabledPlugins"), QStringList{"tickers", "crowdfunding", "bounties", "reddit", "revuo", "localmonero", "calc", "xmrig"}}},
{Config::enabledPlugins, {QS("enabledPlugins"), QStringList{"tickers", "crowdfunding", "bounties", "reddit", "revuo", "calc", "xmrig"}}},
{Config::restartRequired, {QS("restartRequired"), false}},
{Config::tickers, {QS("tickers"), QStringList{"XMR", "BTC", "XMR/BTC"}}},

View file

@ -128,7 +128,6 @@ public:
blockExplorers,
blockExplorer,
redditFrontend,
localMoneroFrontend,
bountiesFrontend, // unused
lastPath,