Development

pull/45/head
dsc 3 years ago
parent c3723ac58a
commit c0cb90bf79

@ -8,7 +8,7 @@ ENV OPENSSL_ROOT_DIR=/usr/local/openssl/
ENV TOR_BIN=/usr/local/tor/bin/tor.exe
RUN apt update && \
DEBIAN_FRONTEND=noninteractive apt install -y curl wget zip automake build-essential cmake gcc-mingw-w64 g++-mingw-w64 gettext git libtool pkg-config \
DEBIAN_FRONTEND=noninteractive apt install -y curl nano wget zip automake build-essential cmake gcc-mingw-w64 g++-mingw-w64 gettext git libtool pkg-config \
python && \
rm -rf /var/lib/apt/lists/*
@ -27,8 +27,12 @@ RUN make -j$THREADS -C /depends HOST=x86_64-w64-mingw32 NO_QT=1
RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
cd qt5 && \
git clone git://code.qt.io/qt/qtbase.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtdeclarative.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtgraphicaleffects.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtimageformats.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtmultimedia.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtquickcontrols.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtquickcontrols2.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtsvg.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qttools.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qttranslations.git -b ${QT_VERSION} --depth 1 && \
@ -38,8 +42,8 @@ RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
./configure --prefix=/depends/x86_64-w64-mingw32 -xplatform win32-g++ \
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
-I $(pwd)/qtbase/src/3rdparty/angle/include \
-opensource -confirm-license -release -static -static-runtime -no-opengl \
-no-avx -openssl -I /depends/x86_64-w64-mingw32/include -L /depends/x86_64-w64-mingw32/lib \
-opensource -confirm-license -release -static -static-runtime -opengl dynamic -no-angle \
-no-feature-qml-worker-script -no-avx -openssl -I /depends/x86_64-w64-mingw32/include -L /depends/x86_64-w64-mingw32/lib \
-qt-freetype -qt-harfbuzz -qt-libjpeg -qt-libpng -qt-pcre -qt-zlib \
-skip gamepad -skip location -skip qt3d -skip qtactiveqt -skip qtandroidextras \
-skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdoc \
@ -47,7 +51,6 @@ RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
-skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport \
-skip qtspeech -skip qttools -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel \
-skip qtwebengine -skip qtwebview -skip qtwinextras -skip qtx11extras \
-skip qtdeclarative -skip qtquickcontrols -skip qtquickcontrols2 \
-skip serialbus -skip webengine \
-nomake examples -nomake tests -nomake tools && \
make -j$THREADS && \
@ -94,7 +97,7 @@ RUN git clone -b v1.2.11 --depth 1 https://github.com/madler/zlib && \
# libpng -> libqrencode
RUN git clone -b libpng16 --depth 1 https://github.com/glennrp/libpng.git && \
cd libpng && \
git reset --hard dbe3e0c43e549a1602286144d94b0666549b18e6 && \
git reset --hard a37d4836519517bdce6cb9d956092321eca3e73b && \
CPPFLAGS="-I/depends/x86_64-w64-mingw32/include" LDFLAGS="-L/depends/x86_64-w64-mingw32/lib" \
./configure --host=x86_64-w64-mingw32 --prefix=/depends/x86_64-w64-mingw32 && \
make -j$THREADS && \
@ -122,11 +125,11 @@ RUN wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz && \
rm -rf $(pwd)
# OpenSSL -> Tor
RUN wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz && \
echo "e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242 openssl-1.1.1i.tar.gz" | sha256sum -c && \
tar -xzf openssl-1.1.1i.tar.gz && \
rm openssl-1.1.1i.tar.gz && \
cd openssl-1.1.1i && \
RUN wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz && \
echo "892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5 openssl-1.1.1k.tar.gz" | sha256sum -c && \
tar -xzf openssl-1.1.1k.tar.gz && \
rm openssl-1.1.1k.tar.gz && \
cd openssl-1.1.1k && \
./Configure mingw64 no-shared no-dso --cross-compile-prefix=x86_64-w64-mingw32- --prefix=/usr/local/openssl && \
make -j$THREADS && \
make -j$THREADS install_sw && \
@ -146,10 +149,9 @@ RUN wget https://github.com/libevent/libevent/releases/download/release-2.1.11-s
make -j$THREADS install && \
rm -rf $(pwd)
ENV TOR_VERSION=0.4.5.5-rc
RUN git clone -b tor-0.4.5.5-rc --depth 1 https://git.torproject.org/tor.git && \
RUN git clone -b tor-0.4.5.7 --depth 1 https://git.torproject.org/tor.git && \
cd tor && \
git reset --hard b36a00e9a9d3eb4b2949951afaa72e45fb7e68cd && \
git reset --hard 83f895c015de55201e5f226f84a866f30f5ee14b && \
./autogen.sh && \
./configure --host=x86_64-w64-mingw32 \
--disable-asciidoc \
@ -172,7 +174,7 @@ RUN git clone -b tor-0.4.5.5-rc --depth 1 https://git.torproject.org/tor.git &&
rm -rf $(pwd) && \
strip -s -D /usr/local/tor/bin/tor.exe
RUN git clone https://git.wownero.com/wowlet/monero-seed.git && \
RUN git clone https://git.featherwallet.org/feather/monero-seed.git && \
cd monero-seed && \
git reset --hard 4674ef09b6faa6fe602ab5ae0b9ca8e1fd7d5e1b && \
cmake -DCMAKE_INSTALL_PREFIX=/depends/x86_64-w64-mingw32 \

@ -187,7 +187,7 @@ bool Path_IsAbsolute( const std::string & sPath )
if( sPath.empty() )
return false;
#if defined( WIN32 )
#ifdef _WIN32
if ( sPath.size() < 3 ) // must be c:\x or \\x at least
return false;
@ -515,7 +515,7 @@ bool Path_Exists( const std::string & sPath )
if( sFixedPath.empty() )
return false;
#if defined( WIN32 )
#ifdef _WIN32
struct _stat buf;
std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
@ -886,7 +886,7 @@ std::string Path_UrlToFilePath( const std::string & sFileUrl )
// -----------------------------------------------------------------------------------------------------
std::string GetUserDocumentsPath()
{
#if defined( WIN32 )
#ifdef _WIN32
WCHAR rwchPath[MAX_PATH];
if ( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )
@ -925,7 +925,7 @@ std::string GetUserDocumentsPath()
// -----------------------------------------------------------------------------------------------------
bool Path_UnlinkFile( const std::string &strFilename )
{
#if defined( WIN32 )
#ifdef _WIN32
std::wstring wsFilename = UTF8to16( strFilename.c_str() );
return ( 0 != DeleteFileW( wsFilename.c_str() ) );
#else

@ -7,7 +7,7 @@
#include <vrcommon/strtools_public.h>
#include <vrcommon/dirtools_public.h>
#if defined( WIN32 )
#ifdef _WIN32
#include <windows.h>
#include <shlobj.h>
@ -36,7 +36,7 @@
/** Returns the root of the directory the system wants us to store user config data in */
static std::string GetAppSettingsPath()
{
#if defined( WIN32 )
#ifdef _WIN32
WCHAR rwchPath[MAX_PATH];
if( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )

@ -21,12 +21,14 @@ TxFiatHistory *AppContext::txFiatHistory = nullptr;
double AppContext::balance = 0;
QMap<QString, QString> AppContext::txDescriptionCache;
QMap<QString, QString> AppContext::txCache;
bool AppContext::isQML = false;
AppContext::AppContext(QCommandLineParser *cmdargs) {
this->m_walletKeysFilesModel = new WalletKeysFilesModel(this, this);
this->network = new QNetworkAccessManager();
this->networkClearnet = new QNetworkAccessManager();
this->cmdargs = cmdargs;
AppContext::isQML = false;
#if defined(Q_OS_MAC)
this->isTorSocks = qgetenv("DYLD_INSERT_LIBRARIES").indexOf("libtorsocks") >= 0;
@ -105,7 +107,7 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
connect(this, &AppContext::setCustomNodes, this->nodes, &Nodes::setCustomNodes);
// Tor & socks proxy
this->ws = new WSClient(this, m_wsUrl);
this->ws = new WSClient(this, wsUrl);
connect(this->ws, &WSClient::WSMessage, this, &AppContext::onWSMessage);
connect(this->ws, &WSClient::connectionEstablished, this, &AppContext::wsConnected);
connect(this->ws, &WSClient::closed, this, &AppContext::wsDisconnected);
@ -163,11 +165,10 @@ void AppContext::initTor() {
this->tor = new Tor(this, this);
this->tor->start();
if (!(isWhonix)) {
if (!isWhonix && wsUrl.contains(".onion")) {
this->networkProxy = new QNetworkProxy(QNetworkProxy::Socks5Proxy, Tor::torHost, Tor::torPort);
this->network->setProxy(*networkProxy);
if (m_wsUrl.host().endsWith(".onion"))
this->ws->webSocket.setProxy(*networkProxy);
this->ws->webSocket.setProxy(*networkProxy);
}
}
@ -409,7 +410,7 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
emit blockHeightWSUpdated(this->heights);
}
else if(cmd == "nodes") {
else if(cmd == "rpc_nodes") {
this->onWSNodes(msg.value("data").toArray());
}
#if defined(HAS_XMRIG)
@ -431,7 +432,7 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
this->onWSReddit(reddit_data);
}
else if(cmd == "wfs") {
else if(cmd == "funding_proposals") {
auto ccs_data = msg.value("data").toArray();
this->onWSCCS(ccs_data);
}
@ -445,6 +446,23 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
auto txFiatHistory_data = msg.value("data").toObject();
AppContext::txFiatHistory->onWSData(txFiatHistory_data);
}
#if defined(HAS_OPENVR)
else if(cmd == "requestPIN") {
auto pin = msg.value("data").toString();
emit pinReceived(pin);
}
else if(cmd == "lookupPIN") {
auto lookup_data = msg.value("data").toObject();
auto address = lookup_data.value("address").toString();
auto pin = lookup_data.value("PIN").toString();
if(address.isEmpty())
emit pinLookupErrorReceived();
else
emit pinLookupReceived(address, pin);
}
#endif
}
void AppContext::onWSNodes(const QJsonArray &nodes) {
@ -813,6 +831,47 @@ void AppContext::onTransactionCreated(PendingTransaction *tx, const QVector<QStr
emit createTransactionSuccess(tx, address);
}
#if defined(HAS_OPENVR)
void AppContext::onAskReceivingPIN() {
// request new receiving PIN from wowlet-backend
if(this->currentWallet == nullptr)
return;
auto address = this->currentWallet->address(0, 1);
QString signature = this->currentWallet->signMessage(address, false, address);
QJsonObject data;
data["signature"] = signature;
data["address"] = address;
QJsonObject obj;
obj["cmd"] = "requestPIN";
obj["data"] = data;
QJsonDocument doc = QJsonDocument(obj);
this->ws->sendMsg(doc.toJson(QJsonDocument::Compact));
}
void AppContext::onLookupReceivingPIN(QString pin) {
// lookup PIN -> address
if(this->currentWallet == nullptr)
return;
auto address = this->currentWallet->address(0, 1);
QString signature = this->currentWallet->signMessage(address, false, address);
QJsonObject data;
data["PIN"] = pin;
QJsonObject obj;
obj["cmd"] = "lookupPIN";
obj["data"] = data;
QJsonDocument doc = QJsonDocument(obj);
this->ws->sendMsg(doc.toJson(QJsonDocument::Compact));
}
#endif
void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){
this->currentWallet->history()->refresh(this->currentWallet->currentSubaddressAccount());
this->currentWallet->coins()->refresh(this->currentWallet->currentSubaddressAccount());

@ -57,6 +57,8 @@ public:
QString defaultWalletDir;
QString defaultWalletDirRoot;
QString tmpTxDescription;
QString wsUrl = "51.195.148.161:1338";
// QString wsUrl = "feathercitimllbmdktu6cmjo3fizgmyfrntntqzu6xguqa2rlq5cgid.onion";
QString walletPath;
QString walletPassword = "";
@ -91,6 +93,7 @@ public:
static QMap<QString, QString> txDescriptionCache;
static QMap<QString, QString> txCache;
static TxFiatHistory *txFiatHistory;
static bool isQML;
// libwalletqt
bool refreshed = false;
@ -111,7 +114,7 @@ public:
void setWindowTitle(bool mining = false);
// Closes the currently opened wallet
void closeWallet(bool emitClosedSignal = true, bool storeWallet = false);
Q_INVOKABLE void closeWallet(bool emitClosedSignal = true, bool storeWallet = false);
void storeWallet();
Q_INVOKABLE QVariantList listWallets() {
@ -137,6 +140,8 @@ public slots:
void onOpenAliasResolve(const QString &openAlias);
void onSetRestoreHeight(quint64 height);
void onPreferredFiatCurrencyChanged(const QString &symbol);
Q_INVOKABLE void onAskReceivingPIN();
Q_INVOKABLE void onLookupReceivingPIN(QString pin);
private slots:
void onWSNodes(const QJsonArray &nodes);
@ -186,6 +191,9 @@ signals:
void suchWowUpdated(const QJsonArray &such_data);
void nodeSourceChanged(NodeSource nodeSource);
void XMRigDownloads(const QJsonObject &data);
void pinLookupReceived(QString address, QString pin);
void pinLookupErrorReceived();
void pinReceived(QString pin);
void setCustomNodes(QList<WowletNode> nodes);
void openAliasResolveError(const QString &msg);
void openAliasResolved(const QString &address, const QString &openAlias);
@ -201,8 +209,6 @@ private:
WalletKeysFilesModel *m_walletKeysFilesModel;
const int m_donationBoundary = 15;
QTimer m_storeTimer;
// @TODO: Replace url
QUrl m_wsUrl = QUrl(QStringLiteral("ws://feathercitimllbmdktu6cmjo3fizgmyfrntntqzu6xguqa2rlq5cgid.onion/ws"));
};
#endif //WOWLET_APPCONTEXT_H

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1156</width>
<height>496</height>
<height>502</height>
</rect>
</property>
<property name="sizePolicy">
@ -101,11 +101,11 @@
<property name="documentMode">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab_3">
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>SuchWow</string>
<string>/r/Wownero</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
@ -119,22 +119,15 @@
<number>0</number>
</property>
<item>
<widget class="SuchWowWidget" name="suchWowWidget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>320</height>
</size>
</property>
</widget>
<widget class="RedditWidget" name="redditWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>WFS</string>
<string>SuchWow</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
@ -148,15 +141,22 @@
<number>0</number>
</property>
<item>
<widget class="CCSWidget" name="ccsWidget" native="true"/>
<widget class="SuchWowWidget" name="suchWowWidget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>320</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<widget class="QWidget" name="tab">
<attribute name="title">
<string>/r/Wownero</string>
<string>WFS</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
@ -170,7 +170,7 @@
<number>0</number>
</property>
<item>
<widget class="RedditWidget" name="redditWidget" native="true"/>
<widget class="CCSWidget" name="ccsWidget" native="true"/>
</item>
</layout>
</widget>
@ -326,7 +326,7 @@
<x>0</x>
<y>0</y>
<width>1156</width>
<height>30</height>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">

@ -51,7 +51,12 @@ int TransactionHistoryModel::columnCount(const QModelIndex &parent) const {
return 0;
}
return TransactionInfoRole::COUNT;
// When wowlet is in QtWidgets mode, it will only use the first 5 columns,
// the rest should be hidden, because it shows in the GUI. So by default we'll
// use 5 as column count. When in QtQuick (QML) mode, we want to expose more columns
// so we can change the column count here.
return AppContext::isQML ? this->COUNT : 5;
}
QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const {

@ -50,6 +50,7 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
int customColumnCount = 5;
signals:
void transactionHistoryChanged();

@ -85,9 +85,8 @@ double Prices::convert(const QString &symbolFrom, const QString &symbolTo, doubl
}
void Prices::fiatPricesReceived(const QJsonObject &data) {
QJsonObject rates = data.value("rates").toObject();
for(const auto &currency: fiat.keys())
if(rates.contains(currency))
this->rates.insert(currency, rates.value(currency).toDouble());
if(data.contains(currency))
this->rates.insert(currency, data.value(currency).toDouble());
emit fiatPricesUpdated();
}

@ -8,16 +8,16 @@
#include "wsclient.h"
#include "appcontext.h"
WSClient::WSClient(AppContext *ctx, const QUrl &url, QObject *parent) :
WSClient::WSClient(AppContext *ctx, const QString &url, QObject *parent) :
QObject(parent),
url(url),
m_ctx(ctx) {
connect(&this->webSocket, &QWebSocket::binaryMessageReceived, this, &WSClient::onbinaryMessageReceived);
connect(&this->webSocket, &QWebSocket::connected, this, &WSClient::onConnected);
connect(&this->webSocket, &QWebSocket::disconnected, this, &WSClient::closed);
connect(&this->webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &WSClient::onError);
m_tor = url.host().endsWith(".onion");
m_tor = url.contains(".onion");
this->url = QString("ws://%1/ws").arg(url);
// Keep websocket connection alive
connect(&m_pingTimer, &QTimer::timeout, [this]{

@ -14,11 +14,11 @@ class WSClient : public QObject
Q_OBJECT
public:
explicit WSClient(AppContext *ctx, const QUrl &url, QObject *parent = nullptr);
explicit WSClient(AppContext *ctx, const QString &url, QObject *parent = nullptr);
void start();
void sendMsg(const QByteArray &data);
QWebSocket webSocket;
QUrl url;
QString url;
signals:
void closed();

@ -10,6 +10,7 @@
#include <QtGui>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QFileInfo>
#include <QQuickView>
#include <QQuickItem>
@ -32,13 +33,24 @@ namespace wowletvr {
WowletVR::WowletVR(AppContext *ctx, QCommandLineParser *parser, QObject *parent) :
QObject(parent), ctx(ctx), m_parser(parser) {
desktopMode = m_parser->isSet("openvr-debug");
AppContext::isQML = true;
// write icon to disk so openvr overlay can refer to it
auto icon = ":/assets/images/wowlet.png";
if (Utils::fileExists(icon)) {
QFile f(icon);
QFileInfo fileInfo(f);
auto icon_path = QDir(ctx->configDirectory).filePath(fileInfo.fileName());
f.copy(icon_path);
f.close();
}
#ifdef Q_OS_WIN
if(desktopMode)
qputenv("QMLSCENE_DEVICE", "softwarecontext");
#endif
qDebug() << "QMLSCENE_DEVICE: " << qgetenv("QMLSCENE_DEVICE");
qInfo() << "OPENSSL VERSION: " << QSslSocket::sslLibraryBuildVersionString();
m_engine.rootContext()->setContextProperty("homePath", QDir::homePath());
m_engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
@ -67,17 +79,20 @@ namespace wowletvr {
// QCoreApplication::setAttribute( Qt::AA_UseDesktopOpenGL );
// QCoreApplication::setAttribute( Qt::AA_Use96Dpi );
if(!desktopMode) {
if(!openvr_init::initializeOpenVR(openvr_init::OpenVrInitializationType::Overlay))
throw std::runtime_error("Error: initializeOpenVR()");
m_controller = new wowletvr::OverlayController(desktopMode, m_engine);
m_engine.rootContext()->setContextProperty("OverlayController", m_controller);
}
auto widgetUrl = QUrl(QStringLiteral("qrc:///main"));
m_component = new QQmlComponent(&m_engine, widgetUrl);
this->errors = m_component->errors();
for (auto &e : this->errors)
qCritical() << "QML Error: " << e.toString().toStdString().c_str();
if(!desktopMode) {
openvr_init::initializeOpenVR(openvr_init::OpenVrInitializationType::Overlay);
m_controller = new wowletvr::OverlayController(desktopMode, m_engine);
}
}
void WowletVR::render() {
@ -97,7 +112,8 @@ namespace wowletvr {
return;
}
m_controller->SetWidget(quickObjItem, displayName, appKey);
auto iconPath = ctx->configDirectory + "/wowlet.png";
m_controller->SetWidget(quickObjItem, displayName, appKey, iconPath.toStdString());
}
WowletVR::~WowletVR() {

@ -7,11 +7,6 @@ import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
import "."
import "mock/Windows.js" as Windows
import "mock/Version.js" as Version
import "mock/NetworkType.js" as NetworkType
import "mock/Settings.js" as Settings
import "mock"
import "qml/common"
import "qml/."
@ -27,10 +22,10 @@ Rectangle {
property var currentWallet;
property bool disconnected: currentWallet ? currentWallet.disconnected : false
property string walletTitle: "lol123"
property string walletTitle: "long wallet name"
property string walletPath: ""
property string statusText: "Idle"
property string balanceFormatted: "Balance: 25928.9543 WOW (+3902.32 WOW unconfirmed)"
property string balanceFormatted: "Balance: 25928.9543 WOW"
property bool wsConnected: false
property int connectionStatus: Wallet.ConnectionStatus_Disconnected;
@ -60,9 +55,9 @@ Rectangle {
MyDialogOkCancelPopup {
id: enterPasswordDialog
dialogTitle: "Enter Password"
dialogTitle: "Enter Wallet Password"
dialogWidth: 700
dialogHeight: 400
dialogHeight: 380
dialogContentItem: ColumnLayout {
RowLayout {
@ -76,7 +71,7 @@ Rectangle {
MyTextField {
id: walletOpenPassword
keyBoardUID: 590
keyBoardUID: 591
color: "#cccccc"
text: ""
Layout.fillWidth: true
@ -105,9 +100,10 @@ Rectangle {
id: createWalletDialog
dialogTitle: "Create New Wallet"
dialogWidth: 700
dialogHeight: 400
dialogHeight: 440
dialogContentItem: ColumnLayout {
spacing: 10
RowLayout {
Layout.topMargin: 16
Layout.leftMargin: 16
@ -141,7 +137,7 @@ Rectangle {
MyTextField {
id: newWalletPassword
keyBoardUID: 591
keyBoardUID: 592
color: "#cccccc"
text: ""
Layout.fillWidth: true
@ -153,7 +149,10 @@ Rectangle {
}
MyText {
Layout.topMargin: 20
Layout.leftMargin: 16
fontSize: 16
fontColor: "#cccccc"
text: "The password field is optional."
}
@ -253,19 +252,11 @@ Rectangle {
}
// function onWalletOpened(Wallet *wallet) {
// currentWallet.heightRefreshed.connect(onHeightRefreshed);
// currentWallet.refreshed.connect(onWalletRefresh)
// currentWallet.updated.connect(onWalletUpdate)
// currentWallet.newBlock.connect(onWalletNewBlock)
// currentWallet.moneySpent.connect(onWalletMoneySent)
// currentWallet.moneyReceived.connect(onWalletMoneyReceived)
// currentWallet.unconfirmedMoneyReceived.connect(onWalletUnconfirmedMoneyReceived)
// currentWallet.transactionCreated.connect(onTransactionCreated)
// currentWallet.connectionStatusChanged.connect(onWalletConnectionStatusChanged)
// currentWallet.deviceButtonRequest.connect(onDeviceButtonRequest);
// currentWallet.deviceButtonPressed.connect(onDeviceButtonPressed);
// currentWallet.walletPassphraseNeeded.connect(onWalletPassphraseNeededWallet);
// currentWallet.transactionCommitted.connect(onTransactionCommitted);
// middlePanel.paymentClicked.connect(handlePayment);

@ -6,7 +6,12 @@
#include <openvr.h>
#include <QDebug>
#include <QMessageBox>
#include "openvr_init.h"
#include "utils/utils.h"
#include <openvr/src/vrcommon/vrpathregistry_public.h>
#include <openvr/src/vrcommon/pathtools_public.h>
namespace openvr_init
{
@ -34,6 +39,14 @@ bool initializeProperly(const OpenVrInitializationType initType) {
bool initializeOpenVR(const OpenVrInitializationType initType)
{
QString vr_pathreg_override = qgetenv("VR_PATHREG_OVERRIDE");
if(!vr_pathreg_override.isEmpty()) {
if(Utils::fileExists(vr_pathreg_override)) {
qCritical() << "Filepath supplied in VR_PATHREG_OVERRIDE not found. Does this path exist?";
return false;
}
}
bool res = initializeProperly(initType);
if(!res)
return false;

@ -81,27 +81,6 @@ OverlayController::OverlayController(bool desktopMode, QQmlEngine& qmlEngine) :
// Set qml context
qmlEngine.rootContext()->setContextProperty("applicationVersion", "1337");
qmlEngine.rootContext()->setContextProperty("vrRuntimePath", getVRRuntimePathUrl());
// Pretty disgusting trick to allow qmlRegisterSingletonType to continue
// working with the lambdas that were already there. The callback function
// in qmlRegisterSingletonType won't work with any lambdas that capture the
// environment. The alternative to making a static pointer to this was
// rewriting all QML to not be singletons, which should probably be done
// whenever possible.
static OverlayController* const objectAddress = this;
constexpr auto qmlSingletonImportName = "ovrwow.wowletvr";
qmlRegisterSingletonType<OverlayController>(
qmlSingletonImportName,
1,
0,
"OverlayController",
[]( QQmlEngine*, QJSEngine* ) {
QObject* obj = objectAddress;
QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership );
return obj;
});
qInfo() << "OPENSSL VERSION: " << QSslSocket::sslLibraryBuildVersionString();
}
OverlayController::~OverlayController() {
@ -138,9 +117,7 @@ void OverlayController::Shutdown() {
m_pFbo.reset();
}
void OverlayController::SetWidget( QQuickItem* quickItem,
const std::string& name,
const std::string& key )
void OverlayController::SetWidget(QQuickItem* quickItem, const std::string& name, const std::string& key, const std::string& iconPath)
{
if ( !m_desktopMode )
{
@ -171,14 +148,9 @@ void OverlayController::SetWidget( QQuickItem* quickItem,
vr::VROverlayFlags_SendVRSmoothScrollEvents,
true );
constexpr auto thumbiconFilename = "img/icons/thumbicon.png";
const auto thumbIconPath = paths::binaryDirectoryFindFile( thumbiconFilename );
if ( !thumbIconPath.empty() ) {
vr::VROverlay()->SetOverlayFromFile( m_ulOverlayThumbnailHandle, thumbIconPath.c_str() );
}
else {
qCritical() << "Could not find thumbnail icon \"" << thumbiconFilename << "\"";
}
// Overlay icon
if (!iconPath.empty())
vr::VROverlay()->SetOverlayFromFile( m_ulOverlayThumbnailHandle, iconPath.c_str() );
// Too many render calls in too short time overwhelm Qt and an
// assertion gets thrown. Therefore we use an timer to delay render
@ -401,6 +373,7 @@ void OverlayController::mainEventLoop() {
case vr::VREvent_DashboardActivated:
{
qDebug() << "Dashboard activated";
emit dashboardActivated();
m_dashboardVisible = true;
}
break;
@ -408,14 +381,17 @@ void OverlayController::mainEventLoop() {
case vr::VREvent_DashboardDeactivated:
{
qDebug() << "Dashboard deactivated";
emit dashboardDeactivated();
m_dashboardVisible = false;
}
break;
case vr::VREvent_KeyboardDone:
{
qDebug() << "VREvent_KeyboardDone";
char keyboardBuffer[1024];
vr::VROverlay()->GetKeyboardText( keyboardBuffer, 1024 );
qDebug() << "emit keyBoardInputSignal()";
emit keyBoardInputSignal( QString( keyboardBuffer ),
static_cast<unsigned long>(
vrEvent.data.keyboard.uUserValue ) );
@ -447,7 +423,7 @@ void OverlayController::showKeyboard(QString existingText, unsigned long userVal
vr::k_EGamepadTextInputModeNormal,
vr::k_EGamepadTextInputLineModeSingleLine,
0,
"Advanced Settings Overlay",
"Wowlet VR",
1024,
existingText.toStdString().c_str(),
userValue);

@ -50,6 +50,7 @@ namespace wowletvr
class OverlayController : public QObject
{
Q_OBJECT
Q_PROPERTY( bool m_desktopMode READ isDesktopMode )
public:
OverlayController(bool desktopMode, QQmlEngine& qmlEngine);
@ -64,9 +65,7 @@ public:
return m_dashboardVisible;
}
void SetWidget( QQuickItem* quickItem,
const std::string& name,
const std::string& key = "" );
void SetWidget(QQuickItem* quickItem, const std::string& name, const std::string& key = "", const std::string& iconPath = "");
bool isDesktopMode()
{
@ -129,6 +128,8 @@ public slots:
signals:
void keyBoardInputSignal( QString input, unsigned long userValue = 0 );
void dashboardDeactivated();
void dashboardActivated();
};
} // namespace wowletvr

@ -40,13 +40,6 @@
<file alias="status_waiting">assets/img/status_waiting.svg</file>
<file alias="status_lagging">assets/img/status_lagging.svg</file>
<file>mock/NetworkType.js</file>
<file>mock/OverlayController.js</file>
<file>mock/Settings.js</file>
<file>mock/Translation.js</file>
<file>mock/Version.js</file>
<file>mock/Windows.js</file>
<file alias="main">main.qml</file>
<file>qml/common/HourComboBox.qml</file>
<file>qml/common/MinuteSecondComboBox.qml</file>

@ -39,7 +39,7 @@ ColumnLayout {
Layout.leftMargin: 40
Layout.rightMargin: 40
Layout.fillWidth: true
text: "Wowlet VR is an alternative QML interface for wowlet and was made over a 4 week period by eating lots of pizzas. It is the world's first cryptocurrency wallet with support for VR. Wowlet is Free and open-source (BSD-3) software and the source code can be studied on git.wownero.com/wowlet/wowlet"
text: "Wowlet VR is an alternative QML interface for wowlet and was made over a 4 week period whilst eating lots of pizzas. It is the world's first cryptocurrency wallet with support for VR. Wowlet is Free and open-source (BSD-3) software and the source code can be studied on git.wownero.com/wowlet/wowlet"
wrap: true
}
@ -51,7 +51,16 @@ ColumnLayout {
Layout.leftMargin: 40
Layout.rightMargin: 40
Layout.fillWidth: true
text: "By \"dsc\" - April 2021. Shoutouts: OpenVR-AdvancedSettings, qvqc, Gatto, cisme, wowario, lza_menace, jwinterm, nioc, asymptotically, azy, selsta, kico, laura, thrmo, rottensox, solar, bl4sty, scoobybejesus (sorry if I forgot anyone!)"
text: "Greetings: matzman666, qvqc, ez, Gatto, cisme, wowario, lza_menace, jwinterm, nioc, asymptotically, azy, selsta, kico, laura, thrmo, rottensox, solar, bl4sty, scoobybejesus"
wrap: true
}
MyText {
Layout.leftMargin: 40
Layout.rightMargin: 40
Layout.fillWidth: true
fontSize: 14
text: "dsc - April 2021"
wrap: true
}

@ -1,12 +0,0 @@
// import QtQuick 2.7
// import QtQuick.Controls 2.0
// import QtQuick.Layouts 1.2
// import QtGraphicalEffects 1.0
// import QtQuick.Window 2.0
// import QtQuick.Controls.Styles 1.4
// import QtQuick.Dialogs 1.2
// //import ovrwow.wowletvr 1.0
// import "common"

@ -9,6 +9,7 @@ import wowlet.Wallet 1.0
Rectangle {
id: root
color: "#1b2939"
width: 1600
height: 800
@ -17,46 +18,64 @@ Rectangle {
property string headerText: "Header Title"
property bool headerShowBackButton: true
property string enteredColor: "#365473"
property string exitedColor: "transparent"
property string pressedColor: "#406288"
signal backClicked();
property Item header: ColumnLayout {
RowLayout {
Button {
id: headerBackButton
Layout.preferredHeight: 50
Layout.preferredWidth: 50
hoverEnabled: true
enabled: headerShowBackButton
visible: headerShowBackButton
contentItem: Image {
source: "qrc:/backarrow"
sourceSize.width: 50
sourceSize.height: 50
Rectangle {
color: "transparent"
Layout.preferredWidth: headerBackButton.width + headerTitleContainer.width + 20
Layout.preferredHeight: 70
RowLayout {
anchors.fill: parent
Rectangle {
id: headerBackButton
visible: headerShowBackButton
color: "transparent"
Layout.preferredHeight: 50
Layout.preferredWidth: 50
Image {
source: "qrc:/backarrow"
sourceSize.width: 50
sourceSize.height: 50
anchors.fill: parent
}
}
Rectangle {
id: headerTitleContainer
color: "transparent"
Layout.preferredHeight: 50
Layout.preferredWidth: headerTitle.width
MyText {
id: headerTitle
text: headerText
font.pointSize: 26
anchors.verticalCenter: parent.verticalCenter
}
}
}
background: Rectangle {
opacity: parent.down ? 1.0 : (parent.activeFocus ? 0.5 : 0.0)
color: "#406288"
radius: 4
MouseArea {
enabled: headerShowBackButton
anchors.fill: parent
}
onHoveredChanged: {
if (hovered) {
forceActiveFocus()
} else {
focus = false
hoverEnabled: true
onEntered: parent.color = root.enteredColor
onExited: parent.color = root.exitedColor
onPressed: parent.color = root.pressedColor
onClicked: {
stackView.pop();
backClicked();
}
}
onClicked: {
backClicked();
stackView.pop();
}
}
MyText {
id: headerTitle
text: headerText
font.pointSize: 30
Layout.leftMargin: headerShowBackButton ? 32 : 0
}
Item {
@ -64,6 +83,7 @@ Rectangle {
Layout.preferredHeight: 50
}
Rectangle {
Layout.preferredWidth: 720
Layout.preferredHeight: 50

@ -23,6 +23,7 @@ TextField {
}
}
onActiveFocusChanged: {
console.log("QML activeFocus()");
if (activeFocus) {
if (!OverlayController.desktopMode) {
OverlayController.showKeyboard(text, keyBoardUID)
@ -32,11 +33,24 @@ TextField {
}
}
onEditingFinished: {
console.log("QML onEditingFinished()");
if (OverlayController.desktopMode && savedText !== text) {
myTextField.onInputEvent(text)
}
}
function onInputEvent(input) {
text = input
}
}
Connections {
target: OverlayController
function onKeyBoardInputSignal(input, userValue) {
console.log("QML onKeyBoardInputSignal(input, userValue)", keyBoardUID);
if (userValue == keyBoardUID) {
if (myTextField.text !== input) {
myTextField.onInputEvent(input)
}
}
}
}
}

@ -13,7 +13,8 @@ import "../common"
Item {
id: root
property var modelx
property var txModel
property int txCount: 0
property var txModelData: []
property int sideMargin: 20
@ -24,6 +25,12 @@ Item {
anchors.fill: parent
spacing: 0
MyText {
visible: txCount == 0
opacity: 0.75
text: "No transactions to display."
}
ListView {
id: listView
visible: true
@ -31,11 +38,11 @@ Item {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 10
model: modelx
model: txModel
interactive: false
delegate: Rectangle {
id: delegate
id: delegate
anchors.left: parent ? parent.left : undefined
anchors.right: parent ? parent.right : undefined
height: 54
@ -64,6 +71,7 @@ Item {
confirmationsRequired = getTxData(index, TransactionHistoryModel.TransactionConfirmationsRequiredRole);
confirmed = confirmations >= confirmationsRequired;
root.txCount = index;
}
RowLayout {
@ -74,16 +82,16 @@ Item {
anchors.right: parent.right
Rectangle {
Layout.preferredWidth: 56
Layout.fillHeight: true
color: "#406288"
Image {
width: 32
height: 32
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
source: {
Layout.preferredWidth: 56
Layout.fillHeight: true
color: "#406288"
Image {
width: 32
height: 32
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
source: {
if(failed) return "qrc:/assets/images/warning.png"
else if(pending) return "qrc:/assets/images/unconfirmed.png"
else if(!confirmed) return "qrc:/assets/images/clock1.png"
@ -91,98 +99,89 @@ Item {
else return "qrc:/assets/images/confirmed.png"
//confirmed ? "qrc:/checkmark_icon" : "qrc:/expired_icon"
}
}
}
}
Rectangle {
Layout.preferredWidth: 300
Layout.leftMargin: 10
Layout.rightMargin: 10
Layout.fillHeight: true
color: "transparent"
Layout.preferredWidth: 300
Layout.leftMargin: 10
Layout.rightMargin: 10
Layout.fillHeight: true
color: "transparent"
MyText {
MyText {
// date
anchors.verticalCenter: parent.verticalCenter
fontSize: 12
anchors.verticalCenter: parent.verticalCenter
fontSize: 12
fontColor: "white"
text: date
text: date
Component.onCompleted: {
parent.Layout.preferredWidth = width;
}
}
Component.onCompleted: {
parent.Layout.preferredWidth = width;
}
}
}
Rectangle {
Layout.fillHeight: true
Layout.leftMargin: 10
color: "transparent"
MyText {
anchors.verticalCenter: parent.verticalCenter
fontSize: 14
text: description !== "" ? description : "..."
Layout.fillHeight: true
Layout.leftMargin: 10
color: "transparent"
MyText {
anchors.verticalCenter: parent.verticalCenter
fontSize: 14
text: description !== "" ? description : "..."
fontColor: description !== "" ? "white" : "#cccccc"
Component.onCompleted: {
parent.Layout.preferredWidth = width;
}
}
Component.onCompleted: {
parent.Layout.preferredWidth = width;
}
}
}
Item {
Layout.fillWidth: true
Layout.fillWidth: true
}
Rectangle {
Layout.preferredWidth: 420
Layout.fillHeight: true
color: "#406288"
MyText {
anchors.right: parent.right
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
fontSize: 14
fontBold: true
text: amount
fontColor: !isout ? "#00d304" : "red"
}
Layout.preferredWidth: 420
Layout.fillHeight: true
color: "#406288"
MyText {
anchors.right: parent.right
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
fontSize: 14
fontBold: true
text: amount
fontColor: !isout ? "#00d304" : "red"
}
}
}
}
}
Item {
Layout.fillHeight: true
}
}
Rectangle {
z: parent.z - 1
color: "transparent"
anchors.fill: parent
}
}
}
}
function getTxData(x, y) {
var idx = modelx.index(x, y);
return modelx.data(idx, 0);
Item {
Layout.fillHeight: true
}
}
function updateTransactionsFromModel() {
// This function copies the items of `appWindow.currentWallet.historyModel` to `root.txModelData`, as a list of javascript objects
if(appWindow.currentWallet == null || typeof appWindow.currentWallet.history === "undefined" ) return;
Rectangle {
z: parent.z - 1
color: "transparent"
anchors.fill: parent
}
var _model = root.model;
var total = 0
var count = _model.rowCount()
root.txModelData = [];
function getTxData(x, y) {
var idx = txModel.index(x, y);
return txModel.data(idx, 0);
}
function onPageCompleted() {
if(currentWallet == null || typeof currentWallet.history === "undefined" ) return;
root.modelx = appWindow.currentWallet.historyModel;
root.txCount = 0;
root.txModel = appWindow.currentWallet.historyModel;
//root.model.sortRole = TransactionHistoryModel.TransactionBlockHeightRole;
//root.model.sort(0, Qt.DescendingOrder);
}

@ -6,249 +6,134 @@ import "."
import "../common"
MyStackViewPage {
id: root
headerText: "Receive"
MyDialogOkPopup {
id: chaperoneMessageDialog
function showMessage(title, text) {
dialogTitle = title
dialogText = text
open()
}
}
MyDialogOkCancelPopup {
id: chaperoneDeleteProfileDialog
property int profileIndex: -1
dialogTitle: "Delete Profile"
dialogText: "Do you really want to delete this profile?"
onClosed: {
if (okClicked) {
ChaperoneTabController.deleteChaperoneProfile(profileIndex)
}
}
}
MyDialogOkCancelPopup {
id: chaperoneNewProfileDialog
dialogTitle: "Create New Profile"
dialogWidth: 800
dialogHeight: 780
dialogContentItem: ColumnLayout {
RowLayout {
Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
MyText {
text: "Name: "
}
MyTextField {
id: chaperoneNewProfileName
keyBoardUID: 390
color: "#cccccc"
text: ""
Layout.fillWidth: true
font.pointSize: 20
function onInputEvent(input) {
chaperoneNewProfileName.text = input
}
}
}
MyText {
Layout.topMargin: 24
text: "What to include:"
}
MyToggleButton {
id: chaperoneNewProfileIncludeGeometry
Layout.leftMargin: 32
text: "Chaperone Geometry"
}
MyToggleButton {
id: chaperoneNewProfileIncludeStyle
Layout.leftMargin: 32
text: "Chaperone Style"
}
MyToggleButton {
id: chaperoneNewProfileIncludeBoundsColor
Layout.leftMargin: 32
text: "Chaperone Color"
}
MyToggleButton {
id: chaperoneNewProfileIncludeVisibility
Layout.leftMargin: 32
text: "Visibility Setting"
}
MyToggleButton {
id: chaperoneNewProfileIncludeFadeDistance
Layout.leftMargin: 32
text: "Fade Distance Setting"
}
MyToggleButton {
id: chaperoneNewProfileIncludeCenterMarker
Layout.leftMargin: 32
text: "Center Marker Setting"
}
MyToggleButton {
id: chaperoneNewProfileIncludePlaySpaceMarker
Layout.leftMargin: 32
text: "Play Space Marker Setting"
}
MyToggleButton {
id: chaperoneNewProfileIncludeFloorBoundsMarker
Layout.leftMargin: 32
text: "Floor Bounds Always On Setting"
}
MyToggleButton {
id: chaperoneNewProfileIncludeForceBounds
Layout.leftMargin: 32
text: "Force Bounds Setting"
}
MyToggleButton {
id: chaperoneNewProfileIncludeProximityWarnings
Layout.leftMargin: 32
text: "Proximity Warning Settings"
}
}
onClosed: {
if (okClicked) {
if (chaperoneNewProfileName.text == "") {
chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Empty profile name.")
} else if (!chaperoneNewProfileIncludeGeometry.checked
&& !chaperoneNewProfileIncludeVisibility.checked
&& !chaperoneNewProfileIncludeFadeDistance.checked
&& !chaperoneNewProfileIncludeCenterMarker.checked
&& !chaperoneNewProfileIncludePlaySpaceMarker.checked
&& !chaperoneNewProfileIncludeFloorBoundsMarker.checked
&& !chaperoneNewProfileIncludeBoundsColor.checked
&& !chaperoneNewProfileIncludeStyle.checked
&& !chaperoneNewProfileIncludeForceBounds.checked
&& !chaperoneNewProfileIncludeProximityWarnings.checked) {
chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Nothing included.")
} else if ( Math.abs(MoveCenterTabController.offsetX) > 0.00000000001
|| Math.abs(MoveCenterTabController.offsetY) > 0.00000000001
|| Math.abs(MoveCenterTabController.offsetZ) > 0.00000000001
|| MoveCenterTabController.rotation !== 0) {
chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Offsets not reset.")
} else {
ChaperoneTabController.addChaperoneProfile(chaperoneNewProfileName.text,
chaperoneNewProfileIncludeGeometry.checked,
chaperoneNewProfileIncludeVisibility.checked,
chaperoneNewProfileIncludeFadeDistance.checked,
chaperoneNewProfileIncludeCenterMarker.checked,
chaperoneNewProfileIncludePlaySpaceMarker.checked,
chaperoneNewProfileIncludeFloorBoundsMarker.checked,
chaperoneNewProfileIncludeBoundsColor.checked,
chaperoneNewProfileIncludeStyle.checked,
chaperoneNewProfileIncludeForceBounds.checked,
chaperoneNewProfileIncludeProximityWarnings.checked)
}
}
}
function openPopup() {
chaperoneNewProfileName.text = ""
chaperoneNewProfileIncludeGeometry.checked = false
chaperoneNewProfileIncludeVisibility.checked = false
chaperoneNewProfileIncludeFadeDistance.checked = false
chaperoneNewProfileIncludeCenterMarker.checked = false
chaperoneNewProfileIncludePlaySpaceMarker.checked = false
chaperoneNewProfileIncludeFloorBoundsMarker.checked = false
chaperoneNewProfileIncludeBoundsColor.checked = false
chaperoneNewProfileIncludeStyle.checked = false
chaperoneNewProfileIncludeForceBounds.checked = false
chaperoneNewProfileIncludeProximityWarnings.checked = false
open()
}
}
content: ColumnLayout {
Layout.fillWidth: true
spacing: 30
MyText {
RowLayout {
spacing: 30
Layout.fillWidth: true
wrap: true
text: "Give the following 4 digit PIN to the person that is sending you Wownero. PIN's are valid for 5 minutes and automatically renew."
}
ColumnLayout {
MyText {
visible: false
fontSize: 14
text: "Currently generating PIN."
}
ColumnLayout {
spacing: 20
Layout.fillWidth: true
Rectangle {
color: "transparent"
Layout.fillWidth: true
Layout.preferredHeight: 120
Text {
visible: true
text: "0 0 0 0"
color: "#ffffff"
font.bold: true
font.pointSize: 40
leftPadding: 20
rightPadding: 20
MyText {
width: parent.width
wrap: true
fontSize: 14
text: "Give the following 4 digit PIN to the person that is sending you Wownero. PIN's are valid for 10 minutes and automatically renew."
}
}
Rectangle {
z: parent.z - 1
anchors.fill: parent
color: "black"
color: "transparent"
Layout.fillWidth: true
Layout.preferredHeight: 220
ColumnLayout {
spacing: 20
MyText {
id: statusText
width: parent.width
visible: true
fontSize: 14
text: "Generating PIN..."
}
Text {
id: pinText
visible: false
text: "- - - -"
color: "#ffffff"
font.bold: true
font.pointSize: 40
leftPadding: 20
rightPadding: 20
Rectangle {
z: parent.z - 1
anchors.fill: parent
color: "black"
}
}
}
}
}
MyText {
id: expireText
visible: true
fontSize: 14
text: "Expires in 40 seconds."
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
}
Rectangle {
color: "#cccccc"
width: 1
Layout.fillHeight: true
}
}
ColumnLayout {
Layout.fillWidth: true
Rectangle {
color: "#cccccc"
height: 1
Layout.topMargin: 10
Layout.fillWidth: true
}
Rectangle {
color: "transparent"
Layout.fillWidth: true
Layout.preferredHeight: 80
Layout.bottomMargin: 20
MyText {
width: parent.width
fontSize: 14
wrap: true
text: "Alternatively, you may use one of the following methods to retreive your address."
}
}
MyText {
Layout.fillWidth: true
wrap: true
text: "Alternatively, you may use one of the following methods."
}
MyPushButton {
id: viewAddress
text: "View address"
Layout.preferredHeight: 70
Layout.fillWidth: true
RowLayout {
Layout.topMargin: 10
onClicked: {
//walletView.push(chaperoneAdditionalPage)
}
}
MyPushButton {
id: viewAddress
text: "View address"
Layout.preferredWidth: 360
MyPushButton {
id: copyToClipboard
text: "Copy address to clipboard"
Layout.preferredHeight: 70
Layout.fillWidth: true
onClicked: {
MyResources.playFocusChangedSound()
walletView.push(chaperoneAdditionalPage)
onClicked: {
MyResources.playFocusChangedSound()
walletView.push(chaperoneAdditionalPage)
}
}
}
MyPushButton {
id: copyToClipboard
text: "Copy address to clipboard"
Layout.preferredWidth: 540
MyPushButton {
id: writeQRcode
text: "Save QR image"
Layout.preferredHeight: 70
Layout.fillWidth: true
onClicked: {
MyResources.playFocusChangedSound()
walletView.push(chaperoneAdditionalPage)
onClicked: {
chaperoneNewProfileDialog.open();
}
}
}
MyPushButton {
id: writeQRcode
text: "QR image"
Layout.preferredWidth: 340
onClicked: {
chaperoneNewProfileDialog.open();
Item {
Layout.fillHeight: true
Layout.fillWidth: true
}
}
}
@ -262,5 +147,58 @@ MyStackViewPage {
function onPageCompleted() {
console.log("onPageCompleted() ReceivePage")
pinAskTimer.start();
askReceivingPIN();
}
function resetPage() {
pinAskTimer.stop();
statusText.visible = true;
statusText.text = "Generating PIN...";
pinText.visible = false;
pinText.text = "- - - -";
}
onBackClicked: {
resetPage();
}
Timer {
id: pinAskTimer
interval: 1000 * 5;
running: false;
repeat: true
onTriggered: askReceivingPIN()
triggeredOnStart: false
}
function askReceivingPIN() {
ctx.onAskReceivingPIN();
}
Connections {
target: ctx
function onPinReceived(pin) {
console.log("onPINReceived", pin);
statusText.visible = false;
pinText.visible = true;
pinText.text = pin[0] + " " + pin[1] + " " + pin[2] + " " + pin[3];
}
}
Connections {
target: OverlayController
function onDashboardDeactivated() {
console.log("onDashboardDeactivated()")
pinAskTimer.stop();
}
function onDashboardActivated() {
console.log("onDashboardActivated()")
if(walletView.currentItem == root)
pinAskTimer.start();
}
}
}

@ -6,8 +6,6 @@ import QtQuick.Window 2.0
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
// import ovrwow.wowletvr 1.0
import "../common"
import "."
@ -63,6 +61,7 @@ MyStackViewPage {
}
walletView.push(receivePage)
receivePage.onPageCompleted();
}
}
@ -74,7 +73,7 @@ MyStackViewPage {
Layout.fillWidth: true
onClicked: {
//MyResources.playFocusChangedSound()
ctx.closeWallet(true, true);
ctx.onCloseWallet(true, true);
mainView.pop();
}
}

@ -11,7 +11,7 @@ MyStackViewPage {
width: 1600
headerText: "Send"
property string destinationAddress: "cool_addy_here"
property string destinationAddress: ""
property string enteredColor: "#365473"
property string exitedColor: "#2c435d"
@ -102,14 +102,6 @@ MyStackViewPage {
}
}
// Connections {
// target: sendStateView.dashPage
// function onTest() {
// sendStack.push(pinPage)
// pinPage.onPageCompleted();
// }
// }
function onPageCompleted(previousView){
sendStateView.state = "dashPage"
}

@ -10,24 +10,6 @@ ColumnLayout {
Layout.fillWidth: true
property string _PINLookup: ""
property int lookupTimeoutSecs: 5;
property int lookupTimeoutCounter: 2;
Timer {
id: lookupTimer
interval: 1000;
running: false;
repeat: true;
onTriggered: {
lookupTimeoutCounter -= 1;
if(lookupTimeoutCounter === 0) {
stop();
root.onLookupTimeout();
}
}
}
MyText {
Layout.fillWidth: true
@ -153,20 +135,6 @@ ColumnLayout {
text: _PINLookup
}
}
RowLayout {
spacing: 30
Layout.fillWidth: true
MyText {
fontBold: true
text: "Timeout:"
}
MyText {
text: lookupTimeoutCounter + " seconds"
}
}
}
// Image {
@ -227,35 +195,18 @@ ColumnLayout {
numPad.enabled = false;
lookupTimer.start();
}
function onLookupTimeout() {
reset();
messagePopup.showMessage("Lookup failed", "Error getting address.")
sendStateView.state = "transferPage";
ctx.onLookupReceivingPIN(code);
}
function onPageCompleted(previousView) {
reset();
}
function onWSPINAdressReceived(pin_code, address) {
// address received from websockets
if(pin_code === _PINLookup) {
sendStateController.destinationAddress = address;
sendStateView.state = "transferPage";
} else {
console.log("PIN lookup received but we timed out already, disregard.")
}
}
function reset() {
// reset state
_PINLookup = "";
lookupTimer.stop();
lookupTimeoutCounter = lookupTimeoutSecs;
idleContainer.visible = true;
foundContainer.visible = false;
loadingContainer.visible = false;
@ -266,4 +217,25 @@ ColumnLayout {
codeDisplay.text = "0 0 0 0";
}
Connections {
target: ctx
function onPinLookupReceived(address, pin) {
console.log("onPinLookupReceived", address);
if(pin === _PINLookup) {
sendStateController.destinationAddress = address;
sendStateView.state = "transferPage";
} else {
console.log("PIN lookup received but we timed out already, disregard.") // undefined behavior
}
}
function onPinLookupErrorReceived() {
console.log("onPinLookupErrorReceived");
messagePopup.showMessage("Lookup failed", "Error getting address.")
reset();
}
}
}

@ -133,7 +133,7 @@ ColumnLayout {
Layout.preferredHeight: 48
MyText {
text: "Wo3ige...YegEia2"
text: destinationAddress
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
}
@ -171,7 +171,7 @@ ColumnLayout {
text: "Enter amount via virtual keyboard"
onClicked: {
OverlayController.showKeyboard(text, "1337")
OverlayController.showKeyboard(text, 1337)
}
}
@ -193,8 +193,9 @@ ColumnLayout {
Connections {
target: OverlayController
function onKeyBoardInputSignal(input, userValue) {
if (userValue == "1337") {
if (userValue == 1337) {
let val = parseFloat(input);
myNumPadSendAmount.onAmountUpdated(val);
}

@ -19,6 +19,7 @@ SuchWowPost::SuchWowPost(AppContext *ctx, QObject *parent) :
m_ctx(ctx) {
m_networkImg = new UtilsNetworking(m_ctx->network, this);
m_networkThumb = new UtilsNetworking(m_ctx->network, this);
m_weburl = QString("http://%1/suchwow").arg(this->m_ctx->wsUrl);
}
void SuchWowPost::onThumbReceived(QByteArray data) {

@ -57,8 +57,7 @@ signals:
void thumbReceived(SuchWowPost *test);
private:
// @TODO: Replace url
QString m_weburl = "http://feathercitimllbmdktu6cmjo3fizgmyfrntntqzu6xguqa2rlq5cgid.onion/suchwow";
QString m_weburl;
AppContext *m_ctx = nullptr;
UtilsNetworking *m_networkThumb = nullptr;
UtilsNetworking *m_networkImg = nullptr;

@ -42,7 +42,7 @@ WalletWizard::WalletWizard(AppContext *ctx, WalletWizard::Page startPage, QWidge
setStartId(Page_Menu);
setButtonText(QWizard::CancelButton, "Close");
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/assets/images/photos/wow20.png"));
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/assets/images/photos/wow40.png"));
setWizardStyle(WizardStyle::ModernStyle);
setOption(QWizard::NoBackButtonOnStartPage);

Loading…
Cancel
Save