Merge pull request 'Android app proof-of-concept' (#48) from dsc/wowlet:android into master
Reviewed-on: #48pull/53/head
commit
499ad4a3aa
@ -0,0 +1,245 @@
|
|||||||
|
FROM debian:stretch
|
||||||
|
|
||||||
|
ARG THREADS=1
|
||||||
|
ARG ANDROID_NDK_REVISION=21d
|
||||||
|
ARG ANDROID_NDK_HASH=bcf4023eb8cb6976a4c7cff0a8a8f145f162bf4d
|
||||||
|
ARG ANDROID_SDK_REVISION=4333796
|
||||||
|
ARG ANDROID_SDK_HASH=92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9
|
||||||
|
ARG QT_VERSION=5.15.2
|
||||||
|
|
||||||
|
WORKDIR /opt/android
|
||||||
|
ENV WORKDIR=/opt/android
|
||||||
|
|
||||||
|
ENV ANDROID_NATIVE_API_LEVEL=28
|
||||||
|
ENV ANDROID_API=android-${ANDROID_NATIVE_API_LEVEL}
|
||||||
|
ENV ANDROID_CLANG=aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang
|
||||||
|
ENV ANDROID_CLANGPP=aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang++
|
||||||
|
ENV ANDROID_NDK_ROOT=${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION}
|
||||||
|
ENV ANDROID_SDK_ROOT=${WORKDIR}/tools
|
||||||
|
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
|
||||||
|
ENV PATH=${JAVA_HOME}/bin:${PATH}
|
||||||
|
ENV PREFIX=${WORKDIR}/prefix
|
||||||
|
ENV TOOLCHAIN_DIR=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y ant automake build-essential ca-certificates-java file gettext git libc6 libncurses5 \
|
||||||
|
libssl-dev libstdc++6 libtinfo5 libtool libz1 openjdk-8-jdk-headless openjdk-8-jre-headless pkg-config python3 \
|
||||||
|
unzip wget
|
||||||
|
|
||||||
|
RUN wget -q https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
|
||||||
|
&& unzip -q sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
|
||||||
|
&& rm -f sdk-tools-linux-${ANDROID_SDK_REVISION}.zip
|
||||||
|
|
||||||
|
RUN wget -q https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
|
||||||
|
&& unzip -q android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
|
||||||
|
&& rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip
|
||||||
|
|
||||||
|
RUN cd ${ANDROID_SDK_ROOT} && echo y | ./bin/sdkmanager "platform-tools" "platforms;${ANDROID_API}" "tools" > /dev/null
|
||||||
|
RUN cp -r ${WORKDIR}/platforms ${WORKDIR}/platform-tools ${ANDROID_SDK_ROOT}
|
||||||
|
|
||||||
|
ENV HOST_PATH=${PATH}
|
||||||
|
ENV PATH=${TOOLCHAIN_DIR}/aarch64-linux-android/bin:${TOOLCHAIN_DIR}/bin:${PATH}
|
||||||
|
|
||||||
|
ARG ZLIB_VERSION=1.2.11
|
||||||
|
ARG ZLIB_HASH=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
|
||||||
|
RUN wget -q https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \
|
||||||
|
&& tar -xzf zlib-${ZLIB_VERSION}.tar.gz \
|
||||||
|
&& rm zlib-${ZLIB_VERSION}.tar.gz \
|
||||||
|
&& cd zlib-${ZLIB_VERSION} \
|
||||||
|
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --prefix=${PREFIX} --static \
|
||||||
|
&& make -j${THREADS} \
|
||||||
|
&& make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 \
|
||||||
|
&& cd qt5 \
|
||||||
|
&& perl init-repository --module-subset=default,-qtwebengine \
|
||||||
|
&& PATH=${HOST_PATH} ./configure -v -developer-build -release \
|
||||||
|
-xplatform android-clang \
|
||||||
|
-android-ndk-platform ${ANDROID_API} \
|
||||||
|
-android-ndk ${ANDROID_NDK_ROOT} \
|
||||||
|
-android-sdk ${ANDROID_SDK_ROOT} \
|
||||||
|
-android-ndk-host linux-x86_64 \
|
||||||
|
-no-dbus \
|
||||||
|
-opengl es2 \
|
||||||
|
-no-use-gold-linker \
|
||||||
|
-no-sql-mysql \
|
||||||
|
-opensource -confirm-license \
|
||||||
|
-android-arch arm64-v8a \
|
||||||
|
-prefix ${PREFIX} \
|
||||||
|
-nomake tools -nomake tests -nomake examples \
|
||||||
|
-skip qtwebengine \
|
||||||
|
-skip qtserialport \
|
||||||
|
-skip qtconnectivity \
|
||||||
|
-skip qttranslations \
|
||||||
|
-skip qtpurchasing \
|
||||||
|
-skip qtgamepad -skip qtscript -skip qtdoc \
|
||||||
|
-no-warnings-are-errors \
|
||||||
|
&& sed -i '213,215d' qtbase/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h \
|
||||||
|
&& PATH=${HOST_PATH} make -j${THREADS} \
|
||||||
|
&& PATH=${HOST_PATH} make -j${THREADS} install \
|
||||||
|
&& cd qttools/src/linguist/lrelease \
|
||||||
|
&& ../../../../qtbase/bin/qmake \
|
||||||
|
&& PATH=${HOST_PATH} make -j${THREADS} install \
|
||||||
|
&& cd ../../../.. \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
ARG ICONV_VERSION=1.16
|
||||||
|
ARG ICONV_HASH=e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04
|
||||||
|
RUN wget -q http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \
|
||||||
|
&& echo "${ICONV_HASH} libiconv-${ICONV_VERSION}.tar.gz" | sha256sum -c \
|
||||||
|
&& tar -xzf libiconv-${ICONV_VERSION}.tar.gz \
|
||||||
|
&& rm -f libiconv-${ICONV_VERSION}.tar.gz \
|
||||||
|
&& cd libiconv-${ICONV_VERSION} \
|
||||||
|
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --build=x86_64-linux-gnu --host=aarch64 --prefix=${PREFIX} --disable-rpath \
|
||||||
|
&& make -j${THREADS} \
|
||||||
|
&& make -j${THREADS} install
|
||||||
|
|
||||||
|
ARG BOOST_VERSION=1_74_0
|
||||||
|
ARG BOOST_VERSION_DOT=1.74.0
|
||||||
|
ARG BOOST_HASH=83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1
|
||||||
|
RUN wget -q https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
|
||||||
|
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||||
|
&& tar -xf boost_${BOOST_VERSION}.tar.bz2 \
|
||||||
|
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
|
||||||
|
&& cd boost_${BOOST_VERSION} \
|
||||||
|
&& PATH=${HOST_PATH} ./bootstrap.sh --prefix=${PREFIX} \
|
||||||
|
&& PATH=${TOOLCHAIN_DIR}/bin:${HOST_PATH} ./b2 --build-type=minimal link=static runtime-link=static \
|
||||||
|
--with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization \
|
||||||
|
--with-system --with-thread --with-locale --build-dir=android --stagedir=android toolset=clang threading=multi \
|
||||||
|
threadapi=pthread target-os=android -sICONV_PATH=${PREFIX} \
|
||||||
|
cflags='--target=aarch64-linux-android' \
|
||||||
|
cxxflags='--target=aarch64-linux-android' \
|
||||||
|
linkflags='--target=aarch64-linux-android --sysroot=${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm64 ${ANDROID_NDK_ROOT}/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so -nostdlib++' \
|
||||||
|
install -j${THREADS} \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
ARG OPENSSL_VERSION=1.1.1g
|
||||||
|
ARG OPENSSL_HASH=ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46
|
||||||
|
RUN wget -q https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
|
||||||
|
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
|
||||||
|
&& rm openssl-${OPENSSL_VERSION}.tar.gz \
|
||||||
|
&& cd openssl-${OPENSSL_VERSION} \
|
||||||
|
&& ANDROID_NDK_HOME=${ANDROID_NDK_ROOT} ./Configure CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} \
|
||||||
|
android-arm64 no-asm no-shared --static \
|
||||||
|
--with-zlib-include=${PREFIX}/include --with-zlib-lib=${PREFIX}/lib \
|
||||||
|
--prefix=${PREFIX} --openssldir=${PREFIX} \
|
||||||
|
&& sed -i 's/CNF_EX_LIBS=-ldl -pthread//g;s/BIN_CFLAGS=-pie $(CNF_CFLAGS) $(CFLAGS)//g' Makefile \
|
||||||
|
&& ANDROID_NDK_HOME=${ANDROID_NDK_ROOT} make -j${THREADS} \
|
||||||
|
&& make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
ARG ZMQ_VERSION=v4.3.3
|
||||||
|
ARG ZMQ_HASH=04f5bbedee58c538934374dc45182d8fc5926fa3
|
||||||
|
RUN git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} --depth 1 \
|
||||||
|
&& cd libzmq \
|
||||||
|
&& git checkout ${ZMQ_HASH} \
|
||||||
|
&& ./autogen.sh \
|
||||||
|
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --prefix=${PREFIX} --host=aarch64-linux-android \
|
||||||
|
--enable-static --disable-shared \
|
||||||
|
&& make -j${THREADS} \
|
||||||
|
&& make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
ARG SODIUM_VERSION=1.0.18
|
||||||
|
ARG SODIUM_HASH=4f5e89fa84ce1d178a6765b8b46f2b6f91216677
|
||||||
|
RUN set -ex \
|
||||||
|
&& git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} --depth 1 \
|
||||||
|
&& cd libsodium \
|
||||||
|
&& test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \
|
||||||
|
&& ./autogen.sh \
|
||||||
|
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --prefix=${PREFIX} --host=aarch64-linux-android --enable-static --disable-shared \
|
||||||
|
&& make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git \
|
||||||
|
&& cd libgpg-error \
|
||||||
|
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \
|
||||||
|
&& ./autogen.sh \
|
||||||
|
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --host=aarch64-linux-android --prefix=${PREFIX} --disable-rpath --disable-shared --enable-static --disable-doc --disable-tests \
|
||||||
|
&& PATH=${TOOLCHAIN_DIR}/bin:${HOST_PATH} make -j${THREADS} \
|
||||||
|
&& make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
RUN git clone -b libgcrypt-1.8.5 --depth 1 git://git.gnupg.org/libgcrypt.git \
|
||||||
|
&& cd libgcrypt \
|
||||||
|
&& git reset --hard 56606331bc2a80536db9fc11ad53695126007298 \
|
||||||
|
&& ./autogen.sh \
|
||||||
|
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --host=aarch64-linux-android --prefix=${PREFIX} --with-gpg-error-prefix=${PREFIX} --disable-shared --enable-static --disable-doc --disable-tests \
|
||||||
|
&& PATH=${TOOLCHAIN_DIR}/bin:${HOST_PATH} make -j${THREADS} \
|
||||||
|
&& make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
RUN cd tools \
|
||||||
|
&& wget -q http://dl-ssl.google.com/android/repository/tools_r25.2.5-linux.zip \
|
||||||
|
&& unzip -q tools_r25.2.5-linux.zip \
|
||||||
|
&& rm -f tools_r25.2.5-linux.zip \
|
||||||
|
&& echo y | ${ANDROID_SDK_ROOT}/tools/android update sdk --no-ui --all --filter build-tools-28.0.3
|
||||||
|
|
||||||
|
RUN git clone -b v3.19.7 --depth 1 https://github.com/Kitware/CMake \
|
||||||
|
&& cd CMake \
|
||||||
|
&& git reset --hard 22612dd53a46c7f9b4c3f4b7dbe5c78f9afd9581 \
|
||||||
|
&& PATH=${HOST_PATH} ./bootstrap \
|
||||||
|
&& PATH=${HOST_PATH} make -j${THREADS} \
|
||||||
|
&& PATH=${HOST_PATH} make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
RUN git clone -b v1.6.35 --depth 1 https://github.com/glennrp/libpng.git && \
|
||||||
|
cd libpng && \
|
||||||
|
git reset --hard c17d164b4467f099b4484dfd4a279da0bc1dbd4a \
|
||||||
|
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ./configure --with-zlib-prefix="${PREFIX}" --host=aarch64-linux-android --prefix=${PREFIX} --disable-shared --enable-static \
|
||||||
|
&& PATH=${TOOLCHAIN_DIR}/bin:${HOST_PATH} make -j${THREADS} \
|
||||||
|
&& make -j${THREADS} install \
|
||||||
|
&& rm -rf $(pwd)
|
||||||
|
|
||||||
|
# @TODO: don't hardcode ANDROID_PLATFORM
|
||||||
|
RUN git clone -b v4.0.2 --depth 1 https://github.com/fukuchi/libqrencode.git && \
|
||||||
|
cd libqrencode && \
|
||||||
|
git reset --hard 59ee597f913fcfda7a010a6e106fbee2595f68e4 && \
|
||||||
|
CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} cmake \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" \
|
||||||
|
-DANDROID_PLATFORM="28" \
|
||||||
|
-DBUILD_SHARED_LIBS=OFF \
|
||||||
|
-DARCH="armv8-a" \
|
||||||
|
-DANDROID_ABI="arm64-v8a" \
|
||||||
|
-DANDROID_TOOLCHAIN=clang \
|
||||||
|
-DCMAKE_PREFIX_PATH="${PREFIX}" \
|
||||||
|
-DPNG_PNG_INCLUDE_DIR="${PREFIX}/include/libpng16/" \
|
||||||
|
-DPNG_LIBRARY="${PREFIX}/lib/libqtlibpng_arm64-v8a.a" \
|
||||||
|
-DICONV_LIBRARY=/opt/android/prefix/lib/libiconv.a \
|
||||||
|
-DICONV_INCLUDE_DIR=/opt/android/prefix/include/ \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="${PREFIX}" && \
|
||||||
|
make -j$THREADS && \
|
||||||
|
make -j$THREADS install && \
|
||||||
|
rm -rf $(pwd)
|
||||||
|
|
||||||
|
RUN ls -al && uname -a
|
||||||
|
|
||||||
|
# @TODO: switch to Release
|
||||||
|
CMD set -ex \
|
||||||
|
&& cd /wowlet \
|
||||||
|
&& mkdir -p build/Android/release \
|
||||||
|
&& cd build/Android/release \
|
||||||
|
&& E=1 cmake \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" \
|
||||||
|
-DCMAKE_PREFIX_PATH="${PREFIX}" \
|
||||||
|
-DCMAKE_FIND_ROOT_PATH="${PREFIX}" \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DARCH="armv8-a" \
|
||||||
|
-DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} \
|
||||||
|
-DANDROID_ABI="arm64-v8a" \
|
||||||
|
-DANDROID_TOOLCHAIN=clang \
|
||||||
|
-DBoost_USE_STATIC_RUNTIME=ON \
|
||||||
|
-DLRELEASE_PATH="${PREFIX}/bin" \
|
||||||
|
-DQT_ANDROID_APPLICATION_BINARY="wowlet" \
|
||||||
|
-DWITH_SCANNER=ON \
|
||||||
|
-DUSE_DEVICE_TREZOR=OFF \
|
||||||
|
-DUSE_SINGLE_BUILDDIR=ON \
|
||||||
|
-DMANUAL_SUBMODULES=1 \
|
||||||
|
-DUSE_SINGLE_BUILDDIR=ON \
|
||||||
|
-DQML=ON \
|
||||||
|
-DANDROID=ON \
|
||||||
|
../../.. \
|
||||||
|
&& PATH=${HOST_PATH} make generate_translations_header \
|
||||||
|
&& make -j${THREADS} -C src \
|
||||||
|
&& make -j${THREADS} apk
|
@ -0,0 +1,45 @@
|
|||||||
|
# Wowlet Mobile (Android)
|
||||||
|
|
||||||
|
This directory contains an unfinished QML application that will show:
|
||||||
|
|
||||||
|
![https://i.imgur.com/yhCsSgj.jpg](https://i.imgur.com/yhCsSgj.jpg)
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Credits go to Monero GUI team for providing the initial work on Qt5+Android.
|
||||||
|
|
||||||
|
Build a Docker image:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build --tag wowlet:android --build-arg THREADS=14 --file Dockerfile.android .
|
||||||
|
```
|
||||||
|
|
||||||
|
Building Wowlet for arm64-v8a:
|
||||||
|
|
||||||
|
```Bash
|
||||||
|
docker run --rm -it -v $PWD:/wowlet -w /wowlet -e THREADS=6 wowlet:android
|
||||||
|
```
|
||||||
|
|
||||||
|
Installing the resulting `.apk` on your device:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb install build/Android/release/android-build//build/outputs/apk/debug/android-build-debug.apk
|
||||||
|
```
|
||||||
|
|
||||||
|
Viewing debug logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb logcat | grep --line-buffered "D wowlet"
|
||||||
|
```
|
||||||
|
|
||||||
|
# Development
|
||||||
|
|
||||||
|
To show this on desktop, you will need the following CMake definitions:
|
||||||
|
|
||||||
|
`-DANDROID_DEBUG=ON -DWITH_SCANNER=ON`
|
||||||
|
|
||||||
|
Start wowlet with the `--android-debug` flag:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./wowlet --android-debug
|
||||||
|
```
|
@ -0,0 +1,102 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
// Copyright (c) 2020-2021, The Monero Project.
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <QResource>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QtGui>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
#include <QtQml>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
#include "libwalletqt/TransactionInfo.h"
|
||||||
|
#include "libwalletqt/TransactionHistory.h"
|
||||||
|
#include "model/TransactionHistoryModel.h"
|
||||||
|
#include "model/TransactionHistoryProxyModel.h"
|
||||||
|
#include "libwalletqt/WalletManager.h"
|
||||||
|
|
||||||
|
#include "utils/keysfiles.h"
|
||||||
|
#include "mobile/main.h"
|
||||||
|
|
||||||
|
namespace mobile {
|
||||||
|
|
||||||
|
Mobile::Mobile(AppContext *ctx, QCommandLineParser *parser, QObject *parent) :
|
||||||
|
QObject(parent), ctx(ctx), m_parser(parser) {
|
||||||
|
AppContext::isQML = true;
|
||||||
|
m_pClipboard = QGuiApplication::clipboard();
|
||||||
|
desktopMode = true;
|
||||||
|
|
||||||
|
// turn on auto tx commits
|
||||||
|
ctx->autoCommitTx = true;
|
||||||
|
|
||||||
|
// QR code scanning from screenshots
|
||||||
|
m_qrScreenshotPreviewPath = ctx->configDirectoryVR + "/screenshot_preview";
|
||||||
|
m_qrScreenshotImagePath = ctx->configDirectoryVR + "/screenshot";
|
||||||
|
m_qrScreenshotTimer.setSingleShot(true);
|
||||||
|
|
||||||
|
qDebug() << "QMLSCENE_DEVICE: " << qgetenv("QMLSCENE_DEVICE");
|
||||||
|
|
||||||
|
m_engine.rootContext()->setContextProperty("homePath", QDir::homePath());
|
||||||
|
m_engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
|
||||||
|
m_engine.rootContext()->setContextProperty("idealThreadCount", QThread::idealThreadCount());
|
||||||
|
m_engine.rootContext()->setContextProperty("qtRuntimeVersion", qVersion());
|
||||||
|
m_engine.rootContext()->setContextProperty("ctx", ctx);
|
||||||
|
|
||||||
|
m_engine.rootContext()->setContextProperty("Mobile", this);
|
||||||
|
qRegisterMetaType<NetworkType::Type>();
|
||||||
|
qmlRegisterType<NetworkType>("wowlet.NetworkType", 1, 0, "NetworkType");
|
||||||
|
|
||||||
|
qmlRegisterUncreatableType<WalletKeysFiles>("wowlet.WalletKeysFiles", 1, 0, "WalletKeysFiles", "WalletKeysFiles can't be instantiated directly");
|
||||||
|
qmlRegisterUncreatableType<Wallet>("wowlet.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly");
|
||||||
|
qmlRegisterType<WalletManager>("wowlet.WalletManager", 1, 0, "WalletManager");
|
||||||
|
|
||||||
|
qmlRegisterUncreatableType<TransactionHistoryProxyModel>("wowlet.TransactionHistoryProxyModel", 1, 0, "TransactionHistoryProxyModel", "TransactionHistoryProxyModel can't be instantiated directly");
|
||||||
|
qmlRegisterUncreatableType<TransactionHistoryModel>("wowlet.TransactionHistoryModel", 1, 0, "TransactionHistoryModel", "TransactionHistoryModel can't be instantiated directly");
|
||||||
|
qmlRegisterUncreatableType<TransactionInfo>("wowlet.TransactionInfo", 1, 0, "TransactionInfo", "TransactionHistory can't be instantiated directly");
|
||||||
|
qmlRegisterUncreatableType<TransactionHistory>("wowlet.TransactionHistory", 1, 0, "TransactionHistory", "TransactionHistory can't be instantiated directly");
|
||||||
|
|
||||||
|
qRegisterMetaType<PendingTransaction::Priority>();
|
||||||
|
qRegisterMetaType<TransactionInfo::Direction>();
|
||||||
|
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
|
||||||
|
|
||||||
|
auto widgetUrl = QUrl(QStringLiteral("qrc:///main"));
|
||||||
|
m_engine.load(widgetUrl);
|
||||||
|
if (m_engine.rootObjects().isEmpty())
|
||||||
|
{
|
||||||
|
qCritical() << "Error: no root objects";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QObject *rootObject = m_engine.rootObjects().first();
|
||||||
|
if (!rootObject)
|
||||||
|
{
|
||||||
|
qCritical() << "Error: no root objects";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wege = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mobile::takeQRScreenshot() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mobile::onCheckQRScreenshot() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Mobile::checkQRScreenshotResults(std::vector<std::string> results) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Mobile::~Mobile() {
|
||||||
|
// bla
|
||||||
|
int wegeg = 1;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
// Copyright (c) 2020-2021, The Monero Project.
|
||||||
|
|
||||||
|
#ifndef WOWLET_MAIN_H
|
||||||
|
#define WOWLET_MAIN_H
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QQmlError>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
#include <QtQml>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <globals.h>
|
||||||
|
|
||||||
|
#include "appcontext.h"
|
||||||
|
#include "utils/config.h"
|
||||||
|
#include "QR-Code-scanner/Decoder.h"
|
||||||
|
|
||||||
|
namespace mobile {
|
||||||
|
|
||||||
|
class Mobile : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Mobile(AppContext *ctx, QCommandLineParser *cmdargs, QObject *parent = nullptr);
|
||||||
|
~Mobile() override;
|
||||||
|
|
||||||
|
QList<QQmlError> errors;
|
||||||
|
|
||||||
|
Q_INVOKABLE double cdiv(double amount) { return amount / globals::cdiv; }
|
||||||
|
Q_INVOKABLE double add(double x, double y) const { return Utils::roundUp(x + y, 4); } // round ceil 4 decimals
|
||||||
|
Q_INVOKABLE double sub(double x, double y) const { return Utils::roundUp(x - y, 4); } // round ceil 4 decimals
|
||||||
|
|
||||||
|
Q_INVOKABLE void onCreateTransaction(const QString &address, const QString &amount_str, const QString description, bool all) {
|
||||||
|
auto amount = WalletManager::amountFromString(amount_str);
|
||||||
|
ctx->onCreateTransaction(address, amount, description, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void setClipboard(const QString &text) {
|
||||||
|
m_pClipboard->setText(text, QClipboard::Clipboard);
|
||||||
|
m_pClipboard->setText(text, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE QString preferredFiat() {
|
||||||
|
return config()->get(Config::preferredFiatCurrency).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE QString fiatToWow(double amount) {
|
||||||
|
auto preferredFiatCurrency = config()->get(Config::preferredFiatCurrency).toString();
|
||||||
|
if (amount <= 0) return QString("0.00");
|
||||||
|
|
||||||
|
double conversionAmount = AppContext::prices->convert(preferredFiatCurrency, "WOW", amount);
|
||||||
|
return QString("%1").arg(QString::number(conversionAmount, 'f', 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE QString wowToFiat(double amount) {
|
||||||
|
auto preferredFiatCurrency = config()->get(Config::preferredFiatCurrency).toString();
|
||||||
|
if (amount <= 0) return QString("0.00");
|
||||||
|
|
||||||
|
double conversionAmount = AppContext::prices->convert("WOW", preferredFiatCurrency, amount);
|
||||||
|
if(conversionAmount <= 0) return QString("0.00");
|
||||||
|
return QString("~%1").arg(QString::number(conversionAmount, 'f', 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void takeQRScreenshot();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void qrScreenshotFailed(QString error);
|
||||||
|
void qrScreenshotSuccess(QString address);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onCheckQRScreenshot();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AppContext *ctx;
|
||||||
|
QQmlApplicationEngine m_engine;
|
||||||
|
|
||||||
|
bool desktopMode = false;
|
||||||
|
QString m_qrScreenshotPreviewPath;
|
||||||
|
QString m_qrScreenshotImagePath;
|
||||||
|
|
||||||
|
QCommandLineParser *m_parser;
|
||||||
|
QClipboard *m_pClipboard;
|
||||||
|
QTimer m_qrScreenshotTimer;
|
||||||
|
QrDecoder m_qrDecoder;
|
||||||
|
|
||||||
|
static QString checkQRScreenshotResults(std::vector<std::string> results);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //WOWLET_MAIN_H
|
@ -0,0 +1,35 @@
|
|||||||
|
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 QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import "."
|
||||||
|
|
||||||
|
import wowlet.Wallet 1.0
|
||||||
|
import wowlet.WalletManager 1.0
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
visible: true
|
||||||
|
id: appWindow
|
||||||
|
width: 1080
|
||||||
|
height: 2400
|
||||||
|
color: "#2C3539"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
Qt.quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Wowlet"
|
||||||
|
color: "white"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pointSize: 62
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file alias="main">main.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
Loading…
Reference in new issue