Development
This commit is contained in:
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,6 +101,28 @@
|
|||
<property name="documentMode">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>/r/Wownero</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<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="RedditWidget" name="redditWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>SuchWow</string>
|
||||
|
@ -152,28 +174,6 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>/r/Wownero</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<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="RedditWidget" name="redditWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -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 ¤cy: 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,53 +18,72 @@ 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
|
||||
}
|
||||
background: Rectangle {
|
||||
opacity: parent.down ? 1.0 : (parent.activeFocus ? 0.5 : 0.0)
|
||||
color: "#406288"
|
||||
radius: 4
|
||||
anchors.fill: parent
|
||||
}
|
||||
onHoveredChanged: {
|
||||
if (hovered) {
|
||||
forceActiveFocus()
|
||||
} else {
|
||||
focus = false
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
backClicked();
|
||||
stackView.pop();
|
||||
|
||||
MouseArea {
|
||||
enabled: headerShowBackButton
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: parent.color = root.enteredColor
|
||||
onExited: parent.color = root.exitedColor
|
||||
onPressed: parent.color = root.pressedColor
|
||||
onClicked: {
|
||||
stackView.pop();
|
||||
backClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
MyText {
|
||||
id: headerTitle
|
||||
text: headerText
|
||||
font.pointSize: 30
|
||||
Layout.leftMargin: headerShowBackButton ? 32 : 0
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
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"
|
||||
Layout.preferredWidth: 56
|
||||
Layout.fillHeight: true
|
||||
color: "#406288"
|
||||
|
||||
Image {
|
||||
width: 32
|
||||
height: 32
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: {
|
||||
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"
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 10
|
||||
color: "transparent"
|
||||
|
||||
MyText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fontSize: 14
|
||||
text: description !== "" ? description : "..."
|
||||
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"
|
||||
Layout.preferredWidth: 420
|
||||
Layout.fillHeight: true
|
||||
color: "#406288"
|
||||
|
||||
MyText {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10
|
||||
MyText {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fontSize: 14
|
||||
fontBold: true
|
||||
text: amount
|
||||
fontColor: !isout ? "#00d304" : "red"
|
||||
}
|
||||
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."
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: true
|
||||
text: "0 0 0 0"
|
||||
color: "#ffffff"
|
||||
font.bold: true
|
||||
font.pointSize: 40
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
ColumnLayout {
|
||||
spacing: 20
|
||||
Layout.fillWidth: true
|
||||
|
||||
Rectangle {
|
||||
z: parent.z - 1
|
||||
anchors.fill: parent
|
||||
color: "black"
|
||||
color: "transparent"
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 120
|
||||
|
||||
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 {
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
|
||||
MyText {
|
||||
id: expireText
|
||||
visible: true
|
||||
fontSize: 14
|
||||
text: "Expires in 40 seconds."
|
||||
Rectangle {
|
||||
color: "#cccccc"
|
||||
width: 1
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
}
|
||||
Rectangle {
|
||||
color: "transparent"
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 80
|
||||
Layout.bottomMargin: 20
|
||||
|
||||
Rectangle {
|
||||
color: "#cccccc"
|
||||
height: 1
|
||||
Layout.topMargin: 10
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
MyText {
|
||||
Layout.fillWidth: true
|
||||
wrap: true
|
||||
text: "Alternatively, you may use one of the following methods."
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.topMargin: 10
|
||||
|
||||
MyPushButton {
|
||||
id: viewAddress
|
||||
text: "View address"
|
||||
Layout.preferredWidth: 360
|
||||
|
||||
onClicked: {
|
||||
MyResources.playFocusChangedSound()
|
||||
walletView.push(chaperoneAdditionalPage)
|
||||
MyText {
|
||||
width: parent.width
|
||||
fontSize: 14
|
||||
wrap: true
|
||||
text: "Alternatively, you may use one of the following methods to retreive your address."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MyPushButton {
|
||||
id: copyToClipboard
|
||||
text: "Copy address to clipboard"
|
||||
Layout.preferredWidth: 540
|
||||
MyPushButton {
|
||||
id: viewAddress
|
||||
text: "View address"
|
||||
Layout.preferredHeight: 70
|
||||
Layout.fillWidth: true
|
||||
|
||||
onClicked: {
|
||||
MyResources.playFocusChangedSound()
|
||||
walletView.push(chaperoneAdditionalPage)
|
||||
onClicked: {
|
||||
//walletView.push(chaperoneAdditionalPage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MyPushButton {
|
||||
id: writeQRcode
|
||||
text: "QR image"
|
||||
Layout.preferredWidth: 340
|
||||
MyPushButton {
|
||||
id: copyToClipboard
|
||||
text: "Copy address to clipboard"
|
||||
Layout.preferredHeight: 70
|
||||
Layout.fillWidth: true
|
||||
|
||||
onClicked: {
|
||||
chaperoneNewProfileDialog.open();
|
||||
onClicked: {
|
||||
MyResources.playFocusChangedSound()
|
||||
walletView.push(chaperoneAdditionalPage)
|
||||
}
|
||||
}
|
||||
|
||||
MyPushButton {
|
||||
id: writeQRcode
|
||||
text: "Save QR image"
|
||||
Layout.preferredHeight: 70
|
||||
Layout.fillWidth: true
|
||||
|
||||
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…
Reference in New Issue