Compare commits

...
Author SHA1 Message Date
rapeafed b6a7e6a355 WowPlayer preview fix #2 2021-10-21 10:41:43 -04:00
rapeafed 4c55f398db WowPlayer preview fix #1 2021-10-20 15:43:10 -04:00
rapeafed 969fd50408 WowPlayer preview 2021-10-16 05:55:16 -04:00
dsc 65ceab6323 Merge pull request 'Fix building the base image' (#82) from bruh/wowlet:bruh-patch-new-boost-link into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/82
2021-09-07 12:56:20 +00:00
bruh 6b2118ecf6 Fix building the base image
Old link was ded.
2021-09-07 12:52:31 +00:00
dsc ca78025735 Merge pull request 'docs: adding Qt build hints for mac os - only v 5.15.1 worked' (#80) from leonardgit6/wowlet:update-docs into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/80
2021-08-29 14:25:56 +00:00
leonardgit6 c5eb13145f docs: fixing Qt configure command 2021-08-29 10:02:45 -04:00
leonardgit6 946443bf8c docs: adding Qt build hints for mac os 2021-08-28 20:27:17 -04:00
dsc ae33c2f1b0 Merge pull request '3.0.0 beta-4 (bulletproof+, solo-mining)' (#79) from v3 into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/79
2021-07-04 13:42:35 +00:00
dsc c97c0d597b beta-4 (bulletproof+, solo-mining) 2021-07-04 15:39:17 +02:00
dsc ee3713b16b Merge pull request 'Bump version to v2.1.0 and fix compile' (#75) from dsc/wowlet:bump-version3 into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/75
2021-05-16 00:02:19 +00:00
dsc ae39e71061 Bump version to v2.1.0 and fix compile 2021-05-16 01:05:05 +02:00
dsc 7e5cac9fa3 Merge pull request 'Improve QR code detection for VR' (#73) from dsc/wowlet:improve-qr-code-detection into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/73
2021-05-15 15:23:57 +00:00
dsc b61b2b1630 Improve QR code detection 2021-05-14 22:46:06 +02:00
wowario 1b1d1db14d Merge pull request 'Failsafe kill feature' (#72) from dsc/wowlet:killme into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/72
2021-05-14 20:21:07 +00:00
dsc 81ec0183ea Failsafe kill feature; to be used in case of an exploit against wowlet and/or a bug that results in loss of funds 2021-05-14 22:16:18 +02:00
wowario f5046cea54 Merge pull request 'Custom SuchWow donation tip amount' (#71) from dsc/wowlet:suchwow-custom-donation-amount into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/71
2021-05-14 20:02:01 +00:00
dsc 624f13b2d9 Custom SuchWow donation tip amount 2021-05-14 22:01:22 +02:00
wowario 0d502f0e45 Merge pull request 'Warn when there is a new version available' (#70) from dsc/wowlet:warn-on-outdated-version into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/70
2021-05-14 19:55:05 +00:00
dsc 6549ca4e1d Warn when there is a new version available 2021-05-14 21:52:13 +02:00
dsc 37578dde7b Merge pull request 'add imgs to assets list' (#65) from wowario/wowlet:banner1 into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/65
2021-05-14 01:38:43 +00:00
wowario 225ae1233e add imgs to assets list 2021-05-11 09:03:04 +03:00
wowario d8cb29c4d4 Merge pull request 'Forum post widget showing latest from forum.wownero.com' (#64) from dsc/wowlet:forum-posts-homewidget into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/64
2021-05-11 05:49:58 +00:00
wowario 502785f233 Merge pull request 'New header image for about dialog' (#63) from dsc/wowlet:image-about-page into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/63
2021-05-11 05:49:45 +00:00
wowario e3cf87906b Merge pull request 'Fix config option reddit' (#62) from dsc/wowlet:fix-settings-reddit into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/62
2021-05-11 05:48:56 +00:00
wowario 5c3821007d Merge pull request 'Optionally (only) hide fiat balance' (#61) from dsc/wowlet:hide-fiat-balance into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/61
2021-05-11 05:48:44 +00:00
dsc c02e084dcf Forum post widget showing latest from forum.wownero.com 2021-05-11 01:56:04 +02:00
dsc 85d4e0ac6d New header image for about dialog 2021-05-10 23:46:49 +02:00
dsc fbca9c9340 Fix config option reddit 2021-05-10 22:57:28 +02:00
dsc d9d0ac1830 Optionally (only) hide fiat balance 2021-05-10 22:14:28 +02:00
wowario 3adb2a6fe7 Merge pull request 'Show random banner on each Wizard window spawn' (#58) from dsc/wowlet:random-banner into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/58
2021-05-10 19:56:29 +00:00
wowario 742ad82b88 Merge pull request 'Redesigned icon by cisme' (#59) from dsc/wowlet:redesigned-icon into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/59
2021-05-10 19:56:09 +00:00
dsc a1ce8f866a Merge pull request 'mo imgs' (#60) from wowario/wowlet:banners into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/60
2021-05-10 19:55:22 +00:00
wowario 24e8942ac5 mo imgs 2021-05-10 22:41:45 +03:00
dsc 3163d68e9e Show random banner on each Wizard window spawn 2021-05-10 19:52:50 +02:00
dsc a6e1a6877f Redesigned icon by cisme 2021-05-10 19:39:32 +02:00
wowario ac1ed1873a Merge pull request 'Include Satoshi ticker, include Monero ticker, and introduce 24h pct change for WOW' (#57) from dsc/wowlet:refactor-tickers into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/57
2021-05-10 17:00:02 +00:00
dsc 2ccefe0883 Include Satoshi ticker, include Monero ticker, and introduce 24h pct change for WOW 2021-05-10 18:56:57 +02:00
wowario 06f09e1f2e Merge pull request 'Fixes connect bug (via context menu) for custom nodes' (#56) from dsc/wowlet:connect-bug into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/56
2021-05-03 07:09:14 +00:00
dsc c3e9fbb25a Fixes connect bug (via context menu) for custom nodes 2021-05-03 01:03:21 +02:00
wowario 096b28318c Merge pull request 'SuchWow improvements' (#55) from dsc/wowlet:suchwow-improvements into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/55
2021-05-02 22:51:03 +00:00
wowario 562d071c62 Merge pull request 'Detect wakeup from hibernate, re-establish websocket connection' (#54) from dsc/wowlet:hibernate-timer into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/54
2021-05-02 22:50:49 +00:00
dsc 474d4b1994 - only download thumbnails for the overview. Download the large format images later - when requesting to view the image. This saves bandwidth.
- Images are properly sorted by date now
2021-05-03 00:46:59 +02:00
dsc 49b55768f7 Detect wakeup from hibernate, re-establish websocket connection 2021-04-30 22:33:15 +02:00
dsc 640a4d72e0 Merge pull request 'Update .deb builder and include XMRig functionality by default on Linux' (#53) from dsc/wowlet:update-deb-and-xmrig into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/53
2021-04-30 20:19:39 +00:00
dsc 0e37f97aa2 Update .deb builder and including XMRig functionality by default for Linux 2021-04-30 20:51:07 +02:00
dsc 499ad4a3aa Merge pull request 'Android app proof-of-concept' (#48) from dsc/wowlet:android into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/48
2021-04-23 08:20:50 +00:00
dsc 8b5bdc4c6a Initial Android app proof-of-concept 2021-04-20 00:06:37 +02:00
dsc cfee938516 Prepare Wowlet codebase for an Android app 2021-04-20 00:02:37 +02:00
dsc c024323eab Prepare CMake for Android deployment and development 2021-04-20 00:00:31 +02:00
dsc a2ad4692a3 Dockerfile for Android compiles. Most of this work is done by xiphon of the Monero GUI team. 2021-04-19 23:04:11 +02:00
122 changed files with 3406 additions and 387 deletions
+3 -4
View File
@@ -1,10 +1,9 @@
[submodule "contrib/KDMacTouchBar"]
path = contrib/KDMacTouchBar
url = https://github.com/KDAB/KDMacTouchBar.git
[submodule "monero"]
path = monero
url = https://git.wownero.com/wownero/wownero
branch = wowlet
[submodule "contrib/quirc"]
path = contrib/quirc
url = https://github.com/dlbeer/quirc.git
[submodule "wownero"]
path = wownero
url = https://git.wownero.com/wownero/wownero.git
+39 -36
View File
@@ -4,18 +4,20 @@ project(wowlet)
message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}")
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "2")
set(VERSION_MAJOR "3")
set(VERSION_MINOR "0")
set(VERSION_REVISION "0")
set(VERSION "beta-2")
set(VERSION "beta-4")
option(FETCH_DEPS "Download dependencies if they are not found" ON)
option(XMRIG "Include XMRig module" ON)
option(OPENVR "Include OpenVR support" OFF)
option(QML "Include QtQuick (QML)" OFF)
option(TOR_BIN "Path to Tor binary to embed inside WOWlet" OFF)
option(XMRIG "Include XMRig module")
option(OPENVR "Include OpenVR support")
option(QML "Include QtQuick (QML)")
option(ANDROID "Android deployment")
option(ANDROID_DEBUG "View the Android app on desktop")
option(TOR_BIN "Path to Tor binary to embed inside WOWlet")
option(STATIC "Link libraries statically, requires static Qt")
option(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
option(USE_DEVICE_TREZOR "Trezor support compilation")
option(DONATE_BEG "Prompt donation window every once in a while" ON)
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")
include(CheckCCompilerFlag)
@@ -28,11 +30,10 @@ include(CheckSymbolExists)
set(WOWNERO_HEAD "f611d5c9e32bc62f1735f6571b0bdb95cc020531")
set(BUILD_GUI_DEPS ON)
set(ARCH "x86-64")
set(BUILD_64 ON)
set(BUILD_64 ON CACHE BOOL "Build 64-bit binaries")
set(INSTALL_VENDORED_LIBUNBOUND ${STATIC})
set(USE_SINGLE_BUILDDIR ON)
if(OPENVR)
if(OPENVR OR ANDROID_DEBUG)
set(QML ON)
endif()
@@ -41,10 +42,7 @@ set(_CMAKE_BUILD_TYPE "")
string(TOUPPER "${CMAKE_BUILD_TYPE}" _CMAKE_BUILD_TYPE)
if("${_CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
set(DEBUG ON)
set(CMAKE_VERBOSE_MAKEFILE ON)
message(STATUS "OPENVR: ${OPENVR}")
message(STATUS "QML: ${QML}")
endif()
check_include_file(sys/prctl.h HAVE_SYS_PRCTL_H)
@@ -59,7 +57,7 @@ if(STATIC)
# manually set the unbound submodule the right commit that has the fix.
# This only works with -DMANUAL_SUBMODULES=1
message(STATUS "applying unbound static build fix contrib/unbound_static.patch")
execute_process(COMMAND bash -c "git -C ${CMAKE_SOURCE_DIR}/monero/external/unbound apply ${CMAKE_SOURCE_DIR}/contrib/unbound_static.patch")
execute_process(COMMAND bash -c "git -C ${CMAKE_SOURCE_DIR}/wownero/external/unbound apply ${CMAKE_SOURCE_DIR}/contrib/unbound_static.patch")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
@@ -92,21 +90,19 @@ function (add_linker_flag_if_supported flag var)
endfunction()
find_package(Git)
if(GIT_FOUND)
message(STATUS "Initializing submodules")
execute_process(COMMAND git "submodule" "update" "--init" "--recursive")
execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/monero OUTPUT_VARIABLE _WOWNERO_HEAD OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _WOWNERO_HEAD STREQUAL WOWNERO_HEAD)
message(FATAL_ERROR "[submodule] Monero HEAD was at ${_WOWNERO_HEAD} but should be at ${WOWNERO_HEAD}")
else()
message(STATUS "[submodule] Wownero HEAD @ ${WOWNERO_HEAD}")
endif()
endif()
#if(GIT_FOUND)
# message(STATUS "Initializing submodules")
# execute_process(COMMAND git "submodule" "update" "--init" "--recursive")
# execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/wownero OUTPUT_VARIABLE _WOWNERO_HEAD OUTPUT_STRIP_TRAILING_WHITESPACE)
# if(NOT _WOWNERO_HEAD STREQUAL WOWNERO_HEAD)
# message(FATAL_ERROR "[submodule] Wownero HEAD was at ${_WOWNERO_HEAD} but should be at ${WOWNERO_HEAD}")
# else()
# message(STATUS "[submodule] Wownero HEAD @ ${WOWNERO_HEAD}")
# endif()
#endif()
add_subdirectory(monero)
set_property(TARGET wallet_merged PROPERTY FOLDER "monero")
get_directory_property(ARCH_WIDTH DIRECTORY "monero" DEFINITION ARCH_WIDTH)
get_directory_property(UNBOUND_LIBRARY DIRECTORY "monero" DEFINITION UNBOUND_LIBRARY)
add_subdirectory(wownero)
get_directory_property(ARCH_WIDTH DIRECTORY "wownero" DEFINITION ARCH_WIDTH)
include(CMakePackageConfigHelpers)
include(VersionMonero)
@@ -173,7 +169,7 @@ find_package(Boost 1.58 REQUIRED COMPONENTS
program_options
locale)
if(UNIX AND NOT APPLE)
if(UNIX AND NOT APPLE AND NOT ANDROID)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
# https://github.com/monero-project/monero-gui/issues/3142#issuecomment-705940446
set(CMAKE_SKIP_RPATH ON)
@@ -195,6 +191,17 @@ if("$ENV{DRONE}" STREQUAL "true")
message(STATUS "We are inside a static compile with Drone CI")
endif()
if(UNIX)
if(NOT CMAKE_PREFIX_PATH AND DEFINED ENV{CMAKE_PREFIX_PATH})
message(STATUS "Using CMAKE_PREFIX_PATH environment variable: '$ENV{CMAKE_PREFIX_PATH}'")
set(CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH})
endif()
if(APPLE AND NOT CMAKE_PREFIX_PATH)
execute_process(COMMAND brew --prefix qt5 OUTPUT_VARIABLE QT5_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
list(APPEND CMAKE_PREFIX_PATH ${QT5_DIR})
endif()
endif()
# To build WOWlet with embedded (and static) Tor, pass CMake -DTOR_BIN=/path/to/tor
if(TOR_BIN)
if(APPLE)
@@ -249,7 +256,7 @@ if(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj")
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt)
if(DEPENDS)
set(ICU_LIBRARIES iconv)
set(ICU_LIBRARIES iconv)
else()
set(ICU_LIBRARIES icuio icuin icuuc icudt icutu iconv)
endif()
@@ -264,7 +271,7 @@ elseif(DRAGONFLY)
set(EXTRA_LIBRARIES execinfo ${COMPAT})
elseif(CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)")
set(EXTRA_LIBRARIES socket nsl resolv)
elseif(NOT MSVC AND NOT DEPENDS)
elseif(NOT MSVC AND NOT DEPENDS AND NOT ANDROID)
find_library(RT rt)
set(EXTRA_LIBRARIES ${RT})
endif()
@@ -384,10 +391,6 @@ if(OPENVR)
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/contrib/openvr")
endif()
if(APPLE)
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/contrib/KDMacTouchBar")
endif()
if(WITH_SCANNER)
add_library(quirc STATIC
contrib/quirc/lib/decode.c
+1 -1
View File
@@ -262,7 +262,7 @@ RUN git clone -b release-64-2 --depth 1 https://github.com/unicode-org/icu && \
make -j$THREADS install && \
rm -rf $(pwd)
RUN wget https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.tar.gz && \
RUN wget https://boostorg.jfrog.io/artifactory/main/release/1.73.0/source/boost_1_73_0.tar.gz && \
echo "9995e192e68528793755692917f9eb6422f3052a53c5e13ba278a228af6c7acf boost_1_73_0.tar.gz" | sha256sum -c && \
tar -xzf boost_1_73_0.tar.gz && \
rm boost_1_73_0.tar.gz && \
+245
View File
@@ -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
+1 -1
View File
@@ -27,7 +27,6 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
CMAKEFLAGS = \
-DARCH=x86_64 \
-DBUILD_64=On \
-DBUILD_TESTS=Off \
-DOPENVR=Off \
@@ -43,6 +42,7 @@ CMAKEFLAGS = \
$(CMAKEFLAGS_EXTRA)
release-static: CMAKEFLAGS += -DBUILD_TAG="linux-x64"
release-static: CMAKEFLAGS += -DXMRIG=OFF
release-static: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
release-static: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
release-static: CMAKEFLAGS += -DREPRODUCIBLE=$(or ${SOURCE_DATE_EPOCH},OFF)
+2 -2
View File
@@ -35,7 +35,7 @@ if(RET)
message(WARNING "Cannot determine current commit. Make sure that you are building either from a Git working tree or from a source archive.")
set(VERSIONTAG "unknown")
set(VERSION_IS_RELEASE "false")
configure_file("monero/src/version.cpp.in" "${TO}")
configure_file("wownero/src/version.cpp.in" "${TO}")
else()
string(SUBSTRING ${COMMIT} 0 9 COMMIT)
message(STATUS "You are currently on commit ${COMMIT}")
@@ -61,5 +61,5 @@ else()
set(VERSION_IS_RELEASE "false")
endif()
endif()
configure_file("monero/src/version.cpp.in" "${TO}")
configure_file("wownero/src/version.cpp.in" "${TO}")
endif()
+2 -2
View File
@@ -4,7 +4,7 @@
find_package(Git QUIET)
# Check what commit we're on
execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse --short=9 HEAD RESULT_VARIABLE RET OUTPUT_VARIABLE COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/monero)
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/wownero)
if(RET)
# Something went wrong, set the version tag to -unknown
@@ -37,7 +37,7 @@ endif()
# Check latest tagged release
execute_process(COMMAND "${GIT_EXECUTABLE}" describe --abbrev=0 RESULT_VARIABLE RET OUTPUT_VARIABLE TAG OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/monero)
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/wownero)
if(RET)
message(WARNING "Cannot determine most recent tag. Make sure that you are building either from a Git working tree or from a source archive.")
+1
View File
@@ -3,6 +3,7 @@
#define WOWLET_VERSION "@VERSION@"
#define WOWLET_BRANCH "@WOWLET_BRANCH@"
#define WOWLET_VERSION_SEMVER "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_REVISION@"
#define MONERO_VERSION "@MONERO_VERSION@"
#define MONERO_BRANCH "@MONERO_BRANCH@"
+6 -6
View File
@@ -22,13 +22,13 @@ mkdir -p "$DEBDIR/usr/share/icons/hicolor/256x256/apps/"
# Copy over assets
cp "$PWD/src/assets/control" "$DEBDIR/DEBIAN/control"
cp "$PWD/src/assets/copyright" "$DEBDIR/debian/copyright"
cp "$PWD/src/assets/copyright" "$DEBDIR/usr/share/doc/wowlet/copyright"
cp "$PWD/src/assets/changelog.gz" "$DEBDIR/usr/share/doc/wowlet/changelog.gz"
cp "$PWD/contrib/debian/control" "$DEBDIR/DEBIAN/control"
cp "$PWD/contrib/debian/copyright" "$DEBDIR/debian/copyright"
cp "$PWD/contrib/debian/copyright" "$DEBDIR/usr/share/doc/wowlet/copyright"
cp "$PWD/contrib/debian/changelog.gz" "$DEBDIR/usr/share/doc/wowlet/changelog.gz"
cp "$PWD/src/assets/org.wowlet.wowlet.metainfo.xml" "$DEBDIR/usr/share/metainfo/org.wowlet.wowlet.metainfo.xml"
cp "$PWD/README.md" "$DEBDIR/usr/share/doc/wowlet/README"
cp "$PWD/SECURITY.md" "$DEBDIR/usr/share/doc/wowlet/SECURITY"
cp "$PWD/docs/SECURITY.md" "$DEBDIR/usr/share/doc/wowlet/SECURITY"
cp "$PWD/build/bin/wowlet" "$DEBDIR/usr/bin/wowlet"
cp "$PWD/src/assets/org.wowlet.wowlet.desktop" "$DEBDIR/usr/share/applications/org.wowlet.wowlet.desktop"
cp "$PWD/src/assets/wowlet.1.gz" "$DEBDIR/usr/share/man/man1/wowlet.1.gz"
@@ -43,4 +43,4 @@ cp "$PWD/src/assets/images/appicons/256x256.png" "$DEBDIR/usr/share/icons/hicolo
# Build deb package
dpkg-deb --build $DEBDIR
mv wowlet.DebDir.deb wowlet_1.0_amd64.deb
mv wowlet.DebDir.deb wowlet_2.1_amd64.deb
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
Package: wowlet
Version: 1.0
Version: 2.1
Section: net
Priority: optional
Architecture: amd64
+23 -8
View File
@@ -27,7 +27,7 @@ Replace `master` with the desired version tag (e.g. `beta-4`) to build the relea
#### 2. Base image
```bash
docker build --tag wowlet:linux --build-arg THREADS=4 .
docker build --tag wowlet:linux --build-arg THREADS=6 .
```
Building the base image takes a while. You only need to build the base image once.
@@ -37,7 +37,7 @@ Building the base image takes a while. You only need to build the base image onc
##### Standalone binary
```bash
docker run --rm -it -v $PWD:/wowlet -w /wowlet wowlet:linux sh -c 'make release-static -j4'
docker run --rm -it -v $PWD:/wowlet -w /wowlet wowlet:linux sh -c 'make release-static -j6'
```
If you're re-running a build make sure to `rm -rf build/` first.
@@ -67,7 +67,7 @@ Replace `master` with the desired version tag (e.g. `beta-4`) to build the relea
```bash
docker build -f Dockerfile.windows --tag wowlet:win --build-arg THREADS=4 .
docker build -f Dockerfile.windows --tag wowlet:win --build-arg THREADS=6 .
```
Building the base image takes a while. You only need to build the base image once.
@@ -75,7 +75,7 @@ Building the base image takes a while. You only need to build the base image onc
#### 3. Build
```bash
docker run --rm -it -v $PWD:/wowlet -w /wowlet wowlet:win sh -c 'make depends root=/depends target=x86_64-w64-mingw32 tag=win-x64 -j4'
docker run --rm -it -v $PWD:/wowlet -w /wowlet wowlet:win sh -c 'make windows root=/depends target=x86_64-w64-mingw32 tag=win-x64 -j6'
```
If you're re-running a build make sure to `rm -rf build/` first.
@@ -96,13 +96,28 @@ Clone the repository.
```bash
git clone --recursive https://git.wownero.com/wowlet/wowlet.git
```
Download Qt5.15.1 from here:
https://download.qt.io/archive/qt/5.15/5.15.1/single/
and build Qt 5.15.1:
Get the latest LTS from here: https://www.qt.io/offline-installers and install.
Build WOWlet.
Qt build on Mac OS:
```bash
CMAKE_PREFIX_PATH=~/Qt5.15.1/5.15.1/clang_64 make mac-release
cd ~/Downloads/qt-everywhere-src-5.15.1
./configure -prefix $PWD/qtbase -release -nomake examples -nomake tests -skip qtwebchannel -skip qtpurchasing -skip webengine -skip qtwebview
make -j 4
```
Build WOWlet:
```bash
CMAKE_PREFIX_PATH=/Users/$username/Downloads/qt-everywhere-src-5.15.1/qtbase/ make mac-release
```
Install and start tor service for ticker/forums:
```bash
brew install tor
brew services start tor
```
The resulting Mac OS application can be found `build/bin/wowlet.app` and will **not** have Tor embedded.
+1 -3
View File
@@ -28,7 +28,7 @@ by running this command: `pandoc wowlet.1.md -s -t man -o wowlet.1 && gzip wowle
apt install -y git cmake libqrencode-dev build-essential cmake libboost-all-dev \
miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev \
libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev \
libprotobuf-dev protobuf-compiler libgcrypt20-dev
libprotobuf-dev protobuf-compiler libgcrypt20-dev libpng-dev
```
## Mac OS
@@ -107,6 +107,4 @@ To skip the wizards and open a wallet directly use `--wallet-file`:
./wowlet --use-local-tor --wallet-file /home/user/Wownero/wallets/bla.keys
```
It is recommended that you use `--stagenet` for development. Testnet is also possible,
but you'll have to provide Wownero a testnet node of your own.
Submodule monero deleted from f611d5c9e3
+96 -20
View File
@@ -40,9 +40,9 @@ file(GLOB SOURCE_FILES
)
if(QML)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets Quick Qml QuickControls2 QmlImportScanner Multimedia)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets Quick Qml QuickControls2 QmlImportScanner Multimedia MultimediaWidgets)
else()
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets Multimedia)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets Multimedia MultimediaWidgets)
endif()
if(OPENVR)
@@ -57,6 +57,15 @@ if(OPENVR)
list(APPEND SOURCE_FILES ${SOURCE_FILES_QML})
endif()
if(ANDROID OR ANDROID_DEBUG)
qt5_add_resources(RESOURCES mobile/qml.qrc)
file(GLOB SOURCE_FILES_QML
"mobile/*.h"
"mobile/*.cpp"
)
list(APPEND SOURCE_FILES ${SOURCE_FILES_QML})
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-deprecated-declarations") # @TODO: removeme
add_subdirectory(libwalletqt)
@@ -98,11 +107,16 @@ if(APPLE)
list(APPEND RESOURCES ${ICON})
endif()
add_executable(wowlet ${EXECUTABLE_FLAG} main.cpp
${SOURCE_FILES}
${RESOURCES}
${ASSETS_TOR}
)
if(NOT ANDROID)
add_executable(wowlet ${EXECUTABLE_FLAG} main.cpp
${SOURCE_FILES}
${RESOURCES}
${ASSETS_TOR}
)
else()
add_library(wowlet SHARED ${SOURCE_FILES} ${RESOURCES})
set_target_properties(wowlet PROPERTIES COMPILE_DEFINITIONS "ANDROID")
endif()
# mac os bundle
set_target_properties(wowlet PROPERTIES
@@ -122,10 +136,10 @@ file(GLOB_RECURSE SRC_HEADERS *.h)
target_include_directories(wowlet PUBLIC
${CMAKE_BINARY_DIR}/src/wowlet_autogen/include
${CMAKE_SOURCE_DIR}/monero/include
${CMAKE_SOURCE_DIR}/monero/src
${CMAKE_SOURCE_DIR}/monero/external/easylogging++
${CMAKE_SOURCE_DIR}/monero/contrib/epee/include
${CMAKE_SOURCE_DIR}/wownero/include
${CMAKE_SOURCE_DIR}/wownero/src
${CMAKE_SOURCE_DIR}/wownero/external/easylogging++
${CMAKE_SOURCE_DIR}/wownero/contrib/epee/include
${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/daemon
@@ -134,6 +148,7 @@ target_include_directories(wowlet PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/utils
${CMAKE_CURRENT_SOURCE_DIR}/tor
${CMAKE_CURRENT_SOURCE_DIR}/qrcode
${CMAKE_CURRENT_SOURCE_DIR}/widgets
${X11_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
@@ -144,6 +159,8 @@ target_include_directories(wowlet PUBLIC
${Qt5Svg_INCLUDE_DIRS}
${Qt5Xml_INCLUDE_DIRS}
${Qt5WebSockets_INCLUDE_DIRS}
${Qt5Multimedia_INCLUDE_DIRS}
${Qt5MultimediaWidgets_INCLUDE_DIRS}
)
if(OPENVR)
@@ -162,6 +179,14 @@ if(XMRIG)
target_compile_definitions(wowlet PRIVATE HAS_XMRIG=1)
endif()
if(ANDROID)
target_compile_definitions(wowlet PRIVATE HAS_ANDROID=1)
endif()
if(ANDROID_DEBUG)
target_compile_definitions(wowlet PRIVATE HAS_ANDROID_DEBUG=1)
endif()
if(OPENVR)
target_compile_definitions(wowlet PRIVATE HAS_OPENVR=1)
target_compile_definitions(wowlet PUBLIC VR_API_PUBLIC)
@@ -208,6 +233,8 @@ target_compile_definitions(wowlet
${Qt5Svg_DEFINITIONS}
${Qt5Xml_DEFINITIONS}
${Qt5WebSockets_DEFINITIONS}
${Qt5Multimedia_DEFINITIONS}
${Qt5MultimediaWidgets_DEFINITIONS}
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
@@ -220,16 +247,18 @@ else()
target_link_libraries(wowlet PUBLIC monero-seed::monero-seed)
endif()
if(ANDROID)
# yolo some hardcoded paths
target_include_directories(wowlet PUBLIC
/opt/android/prefix/include/QtAndroidExtras/
)
endif()
# Link Wownero core libraries
target_link_libraries(wowlet PUBLIC
wallet_merged
${LMDB_LIBRARY}
epee
${UNBOUND_LIBRARY}
${SODIUM_LIBRARY}
wallet_api
easylogging
blockchain_db
hardforks
${Boost_LIBRARIES}
${OPENSSL_LIBRARIES}
${CMAKE_DL_LIBS}
@@ -249,7 +278,9 @@ if(QML)
Qt5::WebSockets
Qt5::Quick
Qt5::Qml
Qt5::QuickControls2)
Qt5::QuickControls2
Qt5::Multimedia
Qt5::MultimediaWidgets)
else()
target_link_libraries(wowlet PUBLIC
Qt5::Core
@@ -258,7 +289,36 @@ else()
Qt5::Network
Qt5::Svg
Qt5::Xml
Qt5::WebSockets)
Qt5::WebSockets
Qt5::Multimedia
Qt5::MultimediaWidgets)
endif()
if(ANDROID)
# yolo some hardcoded paths
target_link_libraries(wowlet PUBLIC
/opt/android/prefix/lib/libQt5QuickTemplates2_arm64-v8a.so
/opt/android/prefix/lib/libQt5Quick_arm64-v8a.so
/opt/android/prefix/lib/libQt5QmlModels_arm64-v8a.so
/opt/android/prefix/lib/libQt5Qml_arm64-v8a.so
/opt/android/prefix/lib/libQt5Svg_arm64-v8a.so
/opt/android/prefix/lib/libQt5Widgets_arm64-v8a.so
/opt/android/prefix/lib/libQt5Gui_arm64-v8a.so
/opt/android/prefix/lib/libQt5Xml_arm64-v8a.so
/opt/android/prefix/lib/libQt5XmlPatterns_arm64-v8a.so
/opt/android/prefix/lib/libQt5Network_arm64-v8a.so
/opt/android/prefix/lib/libQt5Core_arm64-v8a.so
/opt/android/prefix/lib/libQt5VirtualKeyboard_arm64-v8a.so
/opt/android/prefix/lib/libQt5AndroidExtras_arm64-v8a.so
/opt/android/prefix/plugins/bearer/libplugins_bearer_qandroidbearer_arm64-v8a.so
GLESv2
log
z
jnigraphics
android
EGL
c++_shared
)
endif()
# Link random other stuff
@@ -294,7 +354,7 @@ if(OPENVR)
endif()
if(APPLE)
target_link_libraries(wowlet
target_link_libraries(wowlet PUBLIC
KDMacTouchBar
)
target_include_directories(wowlet
@@ -329,3 +389,19 @@ endif()
install(TARGETS wowlet
DESTINATION ${CMAKE_INSTALL_PREFIX}
)
message(STATUS "=============================================")
message(STATUS "VERSION_MAJOR: ${VERSION_MAJOR}")
message(STATUS "VERSION_MINOR: ${VERSION_MINOR}")
message(STATUS "VERSION_REVISION: ${VERSION_REVISION}")
message(STATUS "STATIC: ${STATIC}")
message(STATUS "Include QtQuick (QML): ${QML}")
message(STATUS "VERSION: ${VERSION}")
message(STATUS "Include the XMRIG tab: ${XMRIG}")
message(STATUS "Include Valve's OpenVR library: ${OPENVR}")
message(STATUS "This build is for Android: ${ANDROID}")
message(STATUS "This build is for testing the Android app on desktop: ${ANDROID_DEBUG}")
message(STATUS "TOR_BIN: ${TOR_BIN}")
message(STATUS "DONATE_BEG: ${DONATE_BEG}")
message(STATUS "=============================================")
+128 -50
View File
@@ -6,6 +6,7 @@
#include "appcontext.h"
#include "globals.h"
#include "config-wowlet.h"
// libwalletqt
#include "libwalletqt/TransactionHistory.h"
@@ -30,77 +31,69 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
this->cmdargs = cmdargs;
AppContext::isQML = false;
// OS & env
#if defined(Q_OS_MAC)
this->isMac = true;
this->isTorSocks = qgetenv("DYLD_INSERT_LIBRARIES").indexOf("libtorsocks") >= 0;
#elif __ANDROID__
this->isAndroid = true;
#elif defined(Q_OS_LINUX)
this->isLinux = true;
this->isTorSocks = qgetenv("LD_PRELOAD").indexOf("libtorsocks") >= 0;
#elif defined(Q_OS_WIN)
this->isTorSocks = false;
#endif
this->isTails = TailsOS::detect();
this->isWhonix = WhonixOS::detect();
#elif defined(Q_OS_WIN)
this->isWindows = true;
this->isTorSocks = false;
#endif
this->androidDebug = cmdargs->isSet("android-debug");
//Paths
// Paths
this->pathGenericData = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
this->configRoot = QDir::homePath();
if (isTails) { // #if defined(PORTABLE)
QString portablePath = []{
QString appImagePath = qgetenv("APPIMAGE");
if (appImagePath.isEmpty()) {
qDebug() << "Not an appimage, using currentPath()";
return QDir::currentPath() + "/.wowlet";
}
QFileInfo appImageDir(appImagePath);
return appImageDir.absoluteDir().path() + "/.wowlet";
}();
if (QDir().mkpath(portablePath)) {
this->configRoot = portablePath;
} else {
qCritical() << "Unable to create portable directory: " << portablePath;
}
}
this->accountName = Utils::getUnixAccountName();
this->homeDir = QDir::homePath();
this->configDirectory = QString("%1/.config/wowlet/").arg(this->configRoot);
this->configDirectoryVR = QString("%1%2").arg(this->configDirectory, "vr");
if (isTails) this->setupPathsTails();
QString walletDir = config()->get(Config::walletDirectory).toString();
if (walletDir.isEmpty()) {
#if defined(Q_OS_LINUX) or defined(Q_OS_MAC)
this->defaultWalletDir = QString("%1/Wownero/wallets").arg(this->configRoot);
this->defaultWalletDirRoot = QString("%1/Wownero").arg(this->configRoot);
#elif defined(Q_OS_WIN)
this->defaultWalletDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/Wownero";
this->defaultWalletDirRoot = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
#endif
if(walletDir.isEmpty()) {
if (isAndroid && !androidDebug) setupPathsAndroid();
else if (isWindows) setupPathsWindows();
else if (isLinux || isMac) setupPathsUnix();
} else {
this->defaultWalletDir = walletDir;
this->defaultWalletDirRoot = walletDir;
}
#ifdef __ANDROID__
// can haz disk I/O?
QVector<QString> perms = {
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE"
};
Utils::androidAskPermissions(perms);
#endif
// Create wallet dirs
qDebug() << "creating " << defaultWalletDir;
if (!QDir().mkpath(defaultWalletDir))
qCritical() << "Unable to create dir: " << defaultWalletDir;
this->configDirectory = QString("%1/.config/wowlet/").arg(this->configRoot);
#if defined(Q_OS_UNIX)
if(!this->configDirectory.endsWith('/'))
this->configDirectory = QString("%1/").arg(this->configDirectory);
#endif
this->configDirectoryVR = QString("%1%2").arg(this->configDirectory, "vr");
// Create some directories
createConfigDirectory(this->configDirectory);
// if(this->cmdargs->isSet("stagenet"))
// this->networkType = NetworkType::STAGENET;
// else if(this->cmdargs->isSet("testnet"))
// this->networkType = NetworkType::TESTNET;
// else
this->networkType = NetworkType::MAINNET;
qDebug() << "configRoot: " << this->configRoot;
qDebug() << "homeDir: " << this->homeDir;
qDebug() << "customWalletDir: " << walletDir;
qDebug() << "defaultWalletDir: " << this->defaultWalletDir;
qDebug() << "defaultWalletDirRoot: " << this->defaultWalletDirRoot;
qDebug() << "configDirectory: " << this->configDirectory;
// auto nodeSourceUInt = config()->get(Config::nodeSource).toUInt();
// AppContext::nodeSource = static_cast<NodeSource>(nodeSourceUInt);
this->nodes = new Nodes(this, this->networkClearnet);
@@ -119,6 +112,24 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
this->storeWallet();
});
// If system clock skewed for >= 300 seconds, assume a wake-up from hibernate and reload the websocket connection
if(!this->isAndroid)
m_hibernateTimer.start(3 * 1000);
m_hibernatePreviousTime = std::chrono::steady_clock::now();
connect(&m_hibernateTimer, &QTimer::timeout, [this]() {
const auto now = std::chrono::steady_clock::now();
const auto elapsed = now - m_hibernatePreviousTime;
if(elapsed >= m_hibernateDetectInterval) {
qCritical() << "Clock skew detected, resetting websocket connection";
this->ws->webSocket.abort();
this->ws->start();
}
m_hibernatePreviousTime = now;
});
// restore height lookup
this->initRestoreHeights();
@@ -423,7 +434,6 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
QJsonArray crypto_rates = msg.value("data").toArray();
AppContext::prices->cryptoPricesReceived(crypto_rates);
}
else if(cmd == "fiat_rates") {
QJsonObject fiat_rates = msg.value("data").toObject();
AppContext::prices->fiatPricesReceived(fiat_rates);
@@ -432,21 +442,35 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
QJsonArray reddit_data = msg.value("data").toArray();
this->onWSReddit(reddit_data);
}
else if(cmd == "forum") {
QJsonArray forum_data = msg.value("data").toArray();
this->onWSForum(forum_data);
}
else if(cmd == "funding_proposals") {
auto ccs_data = msg.value("data").toArray();
this->onWSCCS(ccs_data);
}
else if(cmd == "suchwow") {
QJsonArray such_data = msg.value("data").toArray();
emit suchWowUpdated(such_data);
}
else if(cmd == "txFiatHistory") {
auto txFiatHistory_data = msg.value("data").toObject();
AppContext::txFiatHistory->onWSData(txFiatHistory_data);
}
else if(cmd == "wowlet_releases") {
versionPending = msg.value("data").toObject();
auto version_str = versionPending.value("version").toString();
if(Utils::versionOutdated(WOWLET_VERSION_SEMVER, version_str))
emit versionOutdated(version_str, versionPending);
}
else if(cmd == "kill") {
// used *only* in dire emergencies
auto killme = msg.value("data").toBool();
if(killme)
QCoreApplication::quit();
}
#if defined(HAS_OPENVR)
else if(cmd == "requestPIN") {
auto pin = msg.value("data").toString();
@@ -497,6 +521,23 @@ void AppContext::onWSNodes(const QJsonArray &nodes) {
this->nodes->onWSNodesReceived(l);
}
void AppContext::onWSForum(const QJsonArray& forum_data) {
QList<QSharedPointer<ForumPost>> l;
for (auto &&entry: forum_data) {
auto obj = entry.toObject();
auto forumPost = new ForumPost(
obj.value("title").toString(),
obj.value("author").toString(),
obj.value("permalink").toString(),
obj.value("comments").toInt());
QSharedPointer<ForumPost> r = QSharedPointer<ForumPost>(forumPost);
l.append(r);
}
emit forumUpdated(l);
}
void AppContext::onWSReddit(const QJsonArray& reddit_data) {
QList<QSharedPointer<RedditPost>> l;
@@ -558,12 +599,14 @@ void AppContext::createConfigDirectory(const QString &dir) {
}
}
#ifdef HAS_OPENVR
auto config_dir_vr = QString("%1%2").arg(dir, "vr");
if(!Utils::dirExists(config_dir_vr)) {
qDebug() << QString("Creating directory: %1").arg(config_dir_vr);
if (!QDir().mkpath(config_dir_vr))
throw std::runtime_error("Could not create directory " + config_dir_vr.toStdString());
}
#endif
}
void AppContext::createWalletWithoutSpecifyingSeed(const QString &name, const QString &password) {
@@ -949,3 +992,38 @@ void AppContext::refreshModels() {
this->currentWallet->coins()->refresh(this->currentWallet->currentSubaddressAccount());
// Todo: set timer for refreshes
}
void AppContext::setupPathsUnix() {
this->defaultWalletDir = QString("%1/Wownero/wallets").arg(this->configRoot);
this->defaultWalletDirRoot = QString("%1/Wownero").arg(this->configRoot);
}
void AppContext::setupPathsWindows() {
this->defaultWalletDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/Wownero";
this->defaultWalletDirRoot = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
}
void AppContext::setupPathsAndroid() {
this->defaultWalletDir = QString("%1/Wownero/wallets").arg(this->pathGenericData);
this->defaultWalletDirRoot = QString("%1/Wownero").arg(this->pathGenericData);
}
void AppContext::setupPathsTails() {
QString portablePath = []{
QString appImagePath = qgetenv("APPIMAGE");
if (appImagePath.isEmpty()) {
qDebug() << "Not an appimage, using currentPath()";
return QDir::currentPath() + "/.wowlet";
}
QFileInfo appImageDir(appImagePath);
return appImageDir.absoluteDir().path() + "/.wowlet";
}();
if (QDir().mkpath(portablePath)) {
this->configRoot = portablePath;
} else {
qCritical() << "Unable to create portable directory: " << portablePath;
}
}
+20 -1
View File
@@ -19,6 +19,7 @@
#include "utils/txfiathistory.h"
#include "utils/WowletSeed.h"
#include "widgets/RedditPost.h"
#include "widgets/ForumPost.h"
#include "widgets/CCSEntry.h"
#include "utils/RestoreHeightLookup.h"
#include "utils/nodes.h"
@@ -39,7 +40,13 @@ public:
~AppContext() override;
bool isTails = false;
bool isWhonix = false;
bool isAndroid = false;
bool isLinux = false;
bool isMac = false;
bool isWindows = false;
bool isDebug = false;
static bool isQML;
bool androidDebug = false;
// Donation config
const QString donationAddress = "Wo3MWeKwtA918DU4c69hVSNgejdWFCRCuWjShRY66mJkU2Hv58eygJWDJS1MNa2Ge5M1WjUkGHuLqHkweDxwZZU42d16v94mP";
@@ -50,6 +57,7 @@ public:
QString coinName = "wownero";
bool isTorSocks = false;
QString pathGenericData;
QString homeDir;
QString accountName;
QString configRoot;
@@ -98,7 +106,7 @@ public:
static QMap<QString, QString> txDescriptionCache;
static QMap<QString, QString> txCache;
static TxFiatHistory *txFiatHistory;
static bool isQML;
QJsonObject versionPending;
// libwalletqt
bool refreshed = false;
@@ -154,6 +162,7 @@ private slots:
void onWSMessage(const QJsonObject& msg);
void onWSCCS(const QJsonArray &ccs_data);
void onWSReddit(const QJsonArray& reddit_data);
void onWSForum(const QJsonArray& forum_data);
void onMoneySpent(const QString &txId, quint64 amount);
void onMoneyReceived(const QString &txId, quint64 amount);
@@ -192,6 +201,7 @@ signals:
void wsConnected();
void wsDisconnected();
void redditUpdated(QList<QSharedPointer<RedditPost>> &posts);
void forumUpdated(QList<QSharedPointer<ForumPost>> &posts);
void nodesUpdated(QList<QSharedPointer<WowletNode>> &nodes);
void ccsUpdated(QList<QSharedPointer<CCSEntry>> &entries);
void suchWowUpdated(const QJsonArray &such_data);
@@ -210,11 +220,20 @@ signals:
void initiateTransaction();
void endTransaction();
void setTitle(const QString &title); // set window title
void versionOutdated(QString version_string, QJsonObject data);
private:
WalletKeysFilesModel *m_walletKeysFilesModel;
const int m_donationBoundary = 15;
QTimer m_storeTimer;
QTimer m_hibernateTimer;
std::chrono::seconds m_hibernateDetectInterval{300};
std::chrono::time_point<std::chrono::steady_clock> m_hibernatePreviousTime;
void setupPathsUnix();
void setupPathsWindows();
void setupPathsAndroid();
void setupPathsTails();
};
#endif //WOWLET_APPCONTEXT_H
+50
View File
@@ -129,8 +129,56 @@
<file>assets/images/welcome/wow74.png</file>
<file>assets/images/welcome/wow75.png</file>
<file>assets/images/welcome/wow76.png</file>
<file>assets/images/welcome/wow77.png</file>
<file>assets/images/welcome/wow78.png</file>
<file>assets/images/welcome/wow79.png</file>
<file>assets/images/welcome/wow80.png</file>
<file>assets/images/welcome/wow81.png</file>
<file>assets/images/welcome/wow82.png</file>
<file>assets/images/welcome/wow83.png</file>
<file>assets/images/welcome/wow84.png</file>
<file>assets/images/welcome/wow85.png</file>
<file>assets/images/welcome/wow86.png</file>
<file>assets/images/welcome/wow87.png</file>
<file>assets/images/welcome/wow88.png</file>
<file>assets/images/welcome/wow89.png</file>
<file>assets/images/welcome/wow90.png</file>
<file>assets/images/welcome/wow91.png</file>
<file>assets/images/welcome/wow92.png</file>
<file>assets/images/welcome/wow93.png</file>
<file>assets/images/welcome/wow94.png</file>
<file>assets/images/welcome/wow95.png</file>
<file>assets/images/welcome/wow96.png</file>
<file>assets/images/welcome/wow97.png</file>
<file>assets/images/welcome/wow98.png</file>
<file>assets/images/welcome/wow99.png</file>
<file>assets/images/welcome/wow100.png</file>
<file>assets/images/welcome/wow101.png</file>
<file>assets/images/welcome/wow102.png</file>
<file>assets/images/welcome/wow103.png</file>
<file>assets/images/welcome/wow104.png</file>
<file>assets/images/welcome/wow105.png</file>
<file>assets/images/welcome/wow106.png</file>
<file>assets/images/welcome/wow107.png</file>
<file>assets/images/welcome/wow108.png</file>
<file>assets/images/welcome/wow109.png</file>
<file>assets/images/welcome/wow110.png</file>
<file>assets/images/welcome/wow111.png</file>
<file>assets/images/welcome/wow112.png</file>
<file>assets/images/welcome/wow113.png</file>
<file>assets/images/welcome/wow114.png</file>
<file>assets/images/welcome/wow115.png</file>
<file>assets/images/welcome/wow116.png</file>
<file>assets/images/welcome/wow117.png</file>
<file>assets/images/welcome/wow118.png</file>
<file>assets/images/welcome/wow119.png</file>
<file>assets/images/welcome/wow120.png</file>
<file>assets/images/welcome/wow121.png</file>
<file>assets/images/welcome/wow122.png</file>
<file>assets/images/welcome/wow123.png</file>
<file>assets/images/preferences.png</file>
<file>assets/images/preferences.svg</file>
<file>assets/images/credits.jpg</file>
<file>assets/images/qrcode.png</file>
<file>assets/images/qrcode_white.png</file>
<file>assets/images/revealer_c.png</file>
@@ -138,6 +186,7 @@
<file>assets/images/seal.png</file>
<file>assets/images/seed.png</file>
<file>assets/images/speaker.png</file>
<file>assets/images/pls_update.jpg</file>
<file>assets/images/status_connected_fork.png</file>
<file>assets/images/status_connected.png</file>
<file>assets/images/status_connected_proxy_fork.png</file>
@@ -175,6 +224,7 @@
<file>assets/images/xmrig.svg</file>
<file>assets/images/zoom.png</file>
<file>assets/mnemonic_25_english.txt</file>
<file>assets/videos/do_you_even_wow_special_friend.mp4</file>
<file>assets/restore_heights_wownero_mainnet.txt</file>
</qresource>
</RCC>
Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.
+2 -2
View File
@@ -13,8 +13,8 @@ AboutDialog::AboutDialog(QWidget *parent)
ui->setupUi(this);
this->setWindowIcon(QIcon("://assets/images/appicons/64x64.png"));
QPixmap p(":assets/images/illiterate_illuminati.png");
ui->aboutImage->setPixmap(p.scaled(128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation));
QPixmap p(":assets/images/credits.jpg");
ui->aboutImage->setPixmap(p.scaled(800, 600, Qt::KeepAspectRatio, Qt::SmoothTransformation));
auto about = Utils::fileOpenQRC(":assets/about.txt");
auto about_text = Utils::barrayToString(about);
about_text = about_text.replace("<wowlet_version>", WOWLET_VERSION);
+44
View File
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include <QObject>
#include "updatedialog.h"
#include "ui_updatedialog.h"
#include "config-wowlet.h"
UpdateDialog::UpdateDialog(AppContext *ctx, QWidget *parent) :
QDialog(parent),
ctx(ctx),
ui(new Ui::UpdateDialog) {
ui->setupUi(this);
this->setWindowIcon(QIcon("://assets/images/appicons/64x64.png"));
auto version_str = ctx->versionPending.value("version").toString();
QPixmap p(":assets/images/pls_update.jpg");
ui->label_image->setPixmap(p.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->info_label->setText("Current version: " + QString(WOWLET_VERSION_SEMVER) + "\n"
"New version: " + version_str);
ui->label_download->setText("Download: <a href=\"https://git.wownero.com/wowlet/wowlet/releases\">git.wownero.com</a>");
ui->label_download->setTextInteractionFlags(Qt::TextBrowserInteraction);
ui->label_download->setOpenExternalLinks(true);
// checkbox
connect(ui->checkbox_ignore, &QCheckBox::clicked, this, &UpdateDialog::checkboxIgnoreWarning);
this->adjustSize();
}
void UpdateDialog::checkboxIgnoreWarning(bool checked) {
if(checked)
config()->set(Config::ignoreUpdateWarning, WOWLET_VERSION_SEMVER);
else
config()->set(Config::ignoreUpdateWarning, "");
}
UpdateDialog::~UpdateDialog() {
delete ui;
}
+31
View File
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef WOWLET_UPDATEDIALOG_H
#define WOWLET_UPDATEDIALOG_H
#include <QDialog>
#include "appcontext.h"
namespace Ui {
class UpdateDialog;
}
class UpdateDialog : public QDialog
{
Q_OBJECT
public:
explicit UpdateDialog(AppContext *ctx, QWidget *parent = nullptr);
~UpdateDialog() override;
private slots:
void checkboxIgnoreWarning(bool checked);
private:
AppContext *ctx = nullptr;
Ui::UpdateDialog *ui;
};
#endif //WOWLET_UPDATEDIALOG_H
+108
View File
@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UpdateDialog</class>
<widget class="QDialog" name="UpdateDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>349</width>
<height>189</height>
</rect>
</property>
<property name="windowTitle">
<string>Pls update</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_image">
<property name="text">
<string>image</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="info_label">
<property name="text">
<string>info_label</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_download">
<property name="text">
<string>download_label</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkbox_ignore">
<property name="text">
<string>Ignore for now</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>UpdateDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>UpdateDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+2
View File
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2014-2021, The Monero Project.
#include <thread>
#include "Wallet.h"
#include "TransactionHistory.h"
+35 -9
View File
@@ -14,6 +14,12 @@
#include "vr/main.h"
#endif
#ifdef HAS_ANDROID_DEBUG
#include "mobile/main.h"
#elif HAS_ANDROID
#include "mobile/main.h"
#endif
#if defined(Q_OS_WIN)
#include <windows.h>
#endif
@@ -44,6 +50,10 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
argv_ << QString::fromStdString(argv[i]);
}
QCoreApplication::setApplicationName("wowlet");
QCoreApplication::setOrganizationDomain("wownero.org");
QCoreApplication::setOrganizationName("wownero.org");
QCommandLineParser parser;
parser.setApplicationDescription("wowlet");
parser.addHelpOption();
@@ -91,9 +101,12 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
QCommandLineOption openVROption(QStringList() << "openvr", "Start Wowlet OpenVR");
parser.addOption(openVROption);
QCommandLineOption openVRDebugOption(QStringList() << "openvr-debug", "Start the Wowlet VR interface without initializing OpenVR - for debugging purposes.");
QCommandLineOption openVRDebugOption(QStringList() << "openvr-debug", "Start the Wowlet VR interface without initializing OpenVR - for debugging purposes. Requires -DOPENVR=ON CMake definition.");
parser.addOption(openVRDebugOption);
QCommandLineOption androidDebugOption(QStringList() << "android-debug", "Start the Android interface without actually running on Android - for debugging purposes. Requires -DANDROID_DEBUG=ON CMake definition.");
parser.addOption(androidDebugOption);
auto parsed = parser.parse(argv_);
if(!parsed) {
qCritical() << parser.errorText();
@@ -111,13 +124,31 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
bool backgroundAddressEnabled = parser.isSet(backgroundOption);
bool openVREnabled = parser.isSet(openVROption);
bool cliMode = exportContacts || exportTxHistory || backgroundAddressEnabled;
bool androidDebug = parser.isSet(androidDebugOption);
bool android = false;
#ifdef __ANDROID__
android = true;
#endif
qRegisterMetaType<QVector<QString>>();
#ifdef HAS_QML
qputenv("QML_DISABLE_DISK_CACHE", "1");
#endif
#ifdef __ANDROID__
if(android || androidDebug) {
#ifndef HAS_QML
qCritical() << "Wowlet compiled without QML support. Try -DQML=ON";
return 1;
#endif
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication mobile_app(argc, argv);
auto *ctx = new AppContext(&parser);
auto *mobile = new mobile::Mobile(ctx, &parser, &mobile_app);
return mobile_app.exec();
}
#endif
if(openVREnabled) {
#ifdef HAS_OPENVR
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@@ -138,9 +169,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
if(cliMode) {
auto *ctx = new AppContext(&parser);
QCoreApplication cli_app(argc, argv);
QCoreApplication::setApplicationName("wowlet");
QCoreApplication::setOrganizationDomain("wownero.org");
QCoreApplication::setOrganizationName("wownero.org");
ctx->applicationPath = QString(argv[0]);
ctx->isDebug = debugMode;
@@ -191,10 +219,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
QApplication app(argc, argv);
QApplication::setApplicationName("wowlet");
QApplication::setOrganizationDomain("wownero.org");
QApplication::setOrganizationName("wownero.org");
parser.process(app); // Parse again for --help and --version
if(!quiet) {
@@ -204,8 +228,10 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
if (stagenet) info["Mode"] = "Stagenet";
else if (testnet) info["Mode"] = "Testnet";
else info["Mode"] = "Mainnet";
#ifndef QT_NO_SSL
info["SSL"] = QSslSocket::sslLibraryVersionString();
info["SSL build"] = QSslSocket::sslLibraryBuildVersionString();
#endif
for (const auto &k: info.keys())
qWarning().nospace().noquote() << QString("%1: %2").arg(k).arg(info[k]);
}
+137 -14
View File
@@ -7,6 +7,7 @@
#include <QCoreApplication>
#include <QSystemTrayIcon>
#include <QMessageBox>
#include <QGroupBox>
#include <QFileDialog>
#include "mainwindow.h"
@@ -18,11 +19,13 @@
#include "dialog/viewonlydialog.h"
#include "dialog/broadcasttxdialog.h"
#include "dialog/tximportdialog.h"
#include "dialog/updatedialog.h"
#include "dialog/passworddialog.h"
#include "dialog/balancedialog.h"
#include "dialog/WalletCacheDebugDialog.h"
#include "ui_mainwindow.h"
#include "globals.h"
#include "config-wowlet.h"
#include "utils/ColorScheme.h"
// libwalletqt
@@ -38,6 +41,8 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
pMainWindow = this;
ui->setupUi(this);
ui->label_outdated->setVisible(false);
m_windowSettings = new Settings(this);
m_aboutDialog = new AboutDialog(this);
m_windowCalc = new CalcWindow(this);
@@ -88,8 +93,8 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
});
connect(ui->actionReport_bug, &QAction::triggered, [this](){
QMessageBox::information(this, "Reporting Bugs",
"<body>Please report any bugs as issues on our git repo:<br>\n"
"<a href=\"https://git.wownero.com/wowlet/wowlet/issues\" style=\"color: #33A4DF\">https://git.wownero.com/wowlet/wowlet/issues</a><br/><br/>"
"<body>Please report any bugs as issues on the forum:<br>\n"
"<a href=\"https://forum.wownero.com\" style=\"color: #33A4DF\">https://forum.wownero.com/</a><br/><br/>"
"\n"
"Before reporting a bug, upgrade to the most recent version of WOWlet "
"(latest release or git HEAD), and include the version number in your report. "
@@ -129,15 +134,29 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
#endif
// ticker widgets
m_tickerWidgets.append(new TickerWidget(this, "WOW"));
m_tickerWidgets.append(new TickerWidget(this, "BTC"));
for(auto tickerWidget: m_tickerWidgets) {
ui->tickerLayout->addWidget(tickerWidget);
}
m_tickerWOW = new TickerWidget(this, "WOW");
ui->tickerLayout->addWidget(m_tickerWOW);
m_balanceWidget = new TickerWidget(this, "WOW", "Balance", true, true);
m_tickerSAT = new TickerWidget(this, "Satoshi");
m_tickerSAT->hidePct(true);
ui->tickerLayout->addWidget(m_tickerSAT);
m_tickerBTC = new TickerWidget(this, "BTC");
ui->tickerLayout->addWidget(m_tickerBTC);
m_tickerXMR = new TickerWidget(this, "XMR");
ui->tickerLayout->addWidget(m_tickerXMR);
m_balanceWidget = new TickerWidget(this, "Balance");
m_balanceWidget->hidePct(true);
ui->fiatTickerLayout->addWidget(m_balanceWidget);
connect(m_tickerWOW, &TickerWidget::reload, this, &MainWindow::onUpdateWowWidget);
connect(m_tickerBTC, &TickerWidget::reload, this, &MainWindow::onUpdateBTCWidget);
connect(m_tickerSAT, &TickerWidget::reload, this, &MainWindow::onUpdateSATWidget);
connect(m_tickerSAT, &TickerWidget::reload, this, &MainWindow::onUpdateXMRWidget);
connect(m_balanceWidget, &TickerWidget::reload, this, &MainWindow::onUpdateFiatBalanceWidget);
// Send widget
connect(ui->sendWidget, &SendWidget::createTransaction, m_ctx, QOverload<const QString, quint64, const QString, bool>::of(&AppContext::onCreateTransaction));
connect(ui->sendWidget, &SendWidget::createTransactionMultiDest, m_ctx, &AppContext::onCreateTransactionMultiDest);
@@ -167,6 +186,7 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
connect(ui->ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen);
connect(m_ctx, &AppContext::ccsUpdated, ui->ccsWidget->model(), &CCSModel::updateEntries);
connect(m_ctx, &AppContext::redditUpdated, ui->redditWidget->model(), &RedditModel::updatePosts);
connect(m_ctx, &AppContext::forumUpdated, ui->forumWidget->model(), &ForumModel::updatePosts);
connect(m_ctx, &AppContext::suchWowUpdated, ui->suchWowWidget, &SuchWowWidget::onWS);
connect(ui->suchWowWidget, &SuchWowWidget::donate, this, &MainWindow::suchDonate);
@@ -252,11 +272,9 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
}
// settings connects
// Update ticker widget(s) on home tab when settings preferred fiat currency is changed
for(auto tickerWidget: m_tickerWidgets)
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, tickerWidget, &TickerWidget::init);
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, m_balanceWidget, &TickerWidget::init);
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, this, &MainWindow::onUpdateFiatBalanceWidget);
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, m_ctx, &AppContext::onPreferredFiatCurrencyChanged);
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, ui->suchWowWidget, &SuchWowWidget::onPreferredFiatCurrencyChanged);
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, ui->sendWidget, QOverload<>::of(&SendWidget::onPreferredFiatCurrencyChanged));
// Skin
@@ -324,6 +342,9 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
// window title
connect(m_ctx, &AppContext::setTitle, this, &QMainWindow::setWindowTitle);
// Version warning
connect(m_ctx, &AppContext::versionOutdated, this, &MainWindow::onVersionWarning);
// init touchbar
#ifdef Q_OS_MAC
m_touchbar = new KDMacTouchBar(this);
@@ -365,6 +386,7 @@ void MainWindow::initMain() {
this->setEnabled(false);
this->show();
m_wizard = this->createWizard(WalletWizard::Page_Menu);
m_wizard->randomBanner();
m_wizard->show();
this->touchbarShowWizard();
}
@@ -414,6 +436,7 @@ void MainWindow::initMenu() {
connect(ui->actionSeed, &QAction::triggered, this, &MainWindow::showSeedDialog);
connect(ui->actionPassword, &QAction::triggered, this, &MainWindow::showPasswordDialog);
connect(ui->actionKeys, &QAction::triggered, this, &MainWindow::showKeysDialog);
connect(this, &MainWindow::updateDialog, this, &MainWindow::showUpdateDialog);
connect(ui->actionViewOnly, &QAction::triggered, this, &MainWindow::showViewOnlyDialog);
connect(ui->actionStore_wallet, &QAction::triggered, [this]{
m_ctx->currentWallet->store();
@@ -518,6 +541,7 @@ void MainWindow::showWizard(WalletWizard::Page startPage) {
m_wizard->setStartId(startPage);
m_wizard->restart();
m_wizard->setEnabled(true);
m_wizard->randomBanner();
m_wizard->show();
}
@@ -617,6 +641,8 @@ void MainWindow::onWalletOpened(Wallet *wallet) {
this->updatePasswordIcon();
m_updateBytes.start(100);
if(m_showUpdateWarning == 1) emit updateDialog();
}
void MainWindow::onBalanceUpdated(quint64 balance, quint64 spendable) {
@@ -632,7 +658,6 @@ void MainWindow::onBalanceUpdated(quint64 balance, quint64 spendable) {
m_statusLabelBalance->setToolTip("Click for details");
m_statusLabelBalance->setText(label_str);
m_balanceWidget->setHidden(hide);
}
void MainWindow::setStatusText(const QString &text, bool override, int timeout) {
@@ -872,6 +897,12 @@ void MainWindow::updatePasswordIcon() {
m_statusBtnPassword->setIcon(icon);
}
void MainWindow::onVersionWarning(QString current_string, QJsonObject version_data) {
if(m_showUpdateWarning != -1)
m_showUpdateWarning = 1;
ui->label_outdated->setVisible(true);
}
void MainWindow::showRestoreHeightDialog() {
// settings custom restore height is only available for 25 word seeds
auto seed = m_ctx->currentWallet->getCacheAttribute("wowlet.seed");
@@ -897,6 +928,17 @@ void MainWindow::showRestoreHeightDialog() {
});
}
void MainWindow::showUpdateDialog() {
if(config()->get(Config::ignoreUpdateWarning).toString() == WOWLET_VERSION_SEMVER) {
m_showUpdateWarning = -1;
return;
}
auto *dialog = new UpdateDialog(m_ctx, this);
dialog->show();
m_showUpdateWarning = -1;
}
void MainWindow::showKeysDialog() {
auto *dialog = new KeysDialog(m_ctx, this);
dialog->exec();
@@ -1037,7 +1079,9 @@ void MainWindow::showSendScreen(const CCSEntry &entry) {
}
void MainWindow::suchDonate(const QString address) {
double donation = AppContext::prices->convert("EUR", "WOW", 2);
double tipAmount = config()->get(Config::suchWowTipAmount).toDouble();
QString preferredCurrency = config()->get(Config::preferredFiatCurrency).toString();
double donation = AppContext::prices->convert(preferredCurrency, "WOW", tipAmount);
ui->sendWidget->fill(address, "SuchWow contribution :-)", donation);
ui->tabWidget->setCurrentIndex(Tabs::SEND);
}
@@ -1322,6 +1366,85 @@ void MainWindow::showBalanceDialog() {
dialog->deleteLater();
}
void MainWindow::onUpdateSATWidget() {
if(!AppContext::prices->markets.count() || !AppContext::prices->rates.count())
return;
auto wowObj = AppContext::prices->markets["WOW"];
QString satStr = QString::number(wowObj.price_sat);
m_tickerSAT->setFiatText(satStr);
}
void MainWindow::onUpdateWowWidget() {
if(!AppContext::prices->markets.count() || !AppContext::prices->rates.count())
return;
QString fiatCurrency = config()->get(Config::preferredFiatCurrency).toString();
if(!AppContext::prices->rates.contains(fiatCurrency)){
config()->set(Config::preferredFiatCurrency, "USD");
fiatCurrency = "USD";
}
auto wowObj = AppContext::prices->markets["WOW"];
auto currencyText = Utils::amountToCurrencyString(wowObj.price_usd, fiatCurrency);
m_tickerWOW->setFiatText(currencyText);
auto pct24h = AppContext::prices->markets["WOW"].price_usd_change_pct_24h;
auto pct24hText = QString::number(pct24h, 'f', 2);
this->m_tickerWOW->setPctText(pct24hText, pct24h >= 0.0);
}
void MainWindow::onUpdateBTCWidget() {
if(!AppContext::prices->markets.count() || !AppContext::prices->rates.count())
return;
QString fiatCurrency = config()->get(Config::preferredFiatCurrency).toString();
if(!AppContext::prices->rates.contains(fiatCurrency)){
config()->set(Config::preferredFiatCurrency, "USD");
fiatCurrency = "USD";
}
double conversion = AppContext::prices->convert("BTC", fiatCurrency, 1.0);
auto conversionText = Utils::amountToCurrencyString(conversion, fiatCurrency);
m_tickerBTC->setFiatText(conversionText);
auto pct24h = AppContext::prices->markets["BTC"].price_usd_change_pct_24h;
auto pct24hText = QString::number(pct24h, 'f', 2);
this->m_tickerBTC->setPctText(pct24hText, pct24h >= 0.0);
}
void MainWindow::onUpdateXMRWidget() {
if(!AppContext::prices->markets.count() || !AppContext::prices->rates.count())
return;
QString fiatCurrency = config()->get(Config::preferredFiatCurrency).toString();
if(!AppContext::prices->rates.contains(fiatCurrency)){
config()->set(Config::preferredFiatCurrency, "USD");
fiatCurrency = "USD";
}
double conversion = AppContext::prices->convert("XMR", fiatCurrency, 1.0);
auto conversionText = Utils::amountToCurrencyString(conversion, fiatCurrency);
m_tickerXMR->setFiatText(conversionText);
auto pct24h = AppContext::prices->markets["XMR"].price_usd_change_pct_24h;
auto pct24hText = QString::number(pct24h, 'f', 2);
this->m_tickerXMR->setPctText(pct24hText, pct24h >= 0.0);
}
void MainWindow::onUpdateFiatBalanceWidget() {
bool hide = config()->get(Config::hideBalance).toBool() || config()->get(Config::hideFiatBalance).toBool();
m_balanceWidget->setHidden(hide);
if(!AppContext::prices->markets.count() || !AppContext::prices->rates.count())
return;
QString fiatCurrency = config()->get(Config::preferredFiatCurrency).toString();
if(!AppContext::prices->rates.contains(fiatCurrency)){
config()->set(Config::preferredFiatCurrency, "USD");
fiatCurrency = "USD";
}
double conversion = AppContext::prices->convert("WOW", fiatCurrency, AppContext::balance);
auto conversionText = Utils::amountToCurrencyString(conversion, fiatCurrency);
m_balanceWidget->setFiatText(conversionText);
}
QString MainWindow::statusDots() {
m_statusDots++;
m_statusDots = m_statusDots % 4;
+23 -3
View File
@@ -4,6 +4,8 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGlobal>
#ifdef Q_OS_MAC
#include "src/kdmactouchbar.h"
#endif
@@ -23,6 +25,7 @@
#include "calcwindow.h"
#include "widgets/ccswidget.h"
#include "widgets/redditwidget.h"
#include "widgets/forumwidget.h"
#include "widgets/tickerwidget.h"
#include "widgets/xmrigwidget.h"
#include "utils/networking.h"
@@ -35,6 +38,7 @@
#include "dialog/verifyproofdialog.h"
#include "dialog/seeddialog.h"
#include "dialog/passwordchangedialog.h"
#include "dialog/updatedialog.h"
#include "dialog/keysdialog.h"
#include "dialog/aboutdialog.h"
#include "dialog/restoredialog.h"
@@ -81,8 +85,10 @@ public:
};
enum TabsHome {
CCS,
REDDIT
FORUM,
REDDIT,
SUCHWOW,
WFS
};
public slots:
@@ -110,6 +116,7 @@ public slots:
void showSendScreen(const CCSEntry &entry);
void suchDonate(const QString address);
void skinChanged(const QString &skinName);
void onVersionWarning(QString current_string, QJsonObject data);
void menuTorClicked();
void onBlockchainSync(int height, int target);
void onRefreshSync(int height, int target);
@@ -145,7 +152,15 @@ public slots:
void onCreateTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address);
void onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid);
// tickers
void onUpdateWowWidget();
void onUpdateFiatBalanceWidget();
void onUpdateBTCWidget();
void onUpdateSATWidget();
void onUpdateXMRWidget();
signals:
void updateDialog();
void closed();
private:
@@ -161,6 +176,7 @@ private:
void saveGeo();
void restoreGeo();
void showDebugInfo();
void showUpdateDialog();
void showNodeExhaustedMessage();
void showWSNodeExhaustedMessage();
void createUnsignedTxDialog(UnsignedTransaction *tx);
@@ -189,7 +205,10 @@ private:
QAction *m_trayActionSend;
QAction *m_trayActionHistory;
QList<TickerWidget*> m_tickerWidgets;
TickerWidget *m_tickerWOW;
TickerWidget *m_tickerBTC;
TickerWidget *m_tickerSAT;
TickerWidget *m_tickerXMR;
TickerWidget *m_balanceWidget;
// lower status bar
@@ -221,6 +240,7 @@ private:
bool m_constructingTransaction = false;
bool m_statusOverrideActive = false;
QTimer m_txTimer;
int m_showUpdateWarning = 0;
private slots:
void menuToggleTabVisible(const QString &key);
+73 -3
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1156</width>
<height>502</height>
<height>506</height>
</rect>
</property>
<property name="sizePolicy">
@@ -86,6 +86,13 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_outdated">
<property name="text">
<string>Warning: outdated wowlet version</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
@@ -101,9 +108,31 @@
<property name="documentMode">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Forum</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<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="ForumWidget" name="forumWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>/r/Wownero</string>
<string>Reddit</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="leftMargin">
@@ -152,6 +181,35 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_player">
<attribute name="title">
<string>WowPlayer</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_player">
<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="WowPlayerWidget" name="wowPlayerWidget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>320</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>WFS</string>
@@ -326,7 +384,7 @@
<x>0</x>
<y>0</y>
<width>1156</width>
<height>20</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -755,6 +813,18 @@
<header>widgets/suchwowwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>WowPlayerWidget</class>
<extends>QWidget</extends>
<header>widgets/wowplayerwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ForumWidget</class>
<extends>QWidget</extends>
<header>widgets/forumwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="assets.qrc"/>
+45
View File
@@ -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
```
+102
View File
@@ -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;
}
}
+92
View File
@@ -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
+35
View File
@@ -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
}
}
+5
View File
@@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file alias="main">main.qml</file>
</qresource>
</RCC>
+104
View File
@@ -0,0 +1,104 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "ForumModel.h"
ForumModel::ForumModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
void ForumModel::clear() {
beginResetModel();
m_posts.clear();
endResetModel();
}
void ForumModel::updatePosts(const QList<QSharedPointer<ForumPost>>& posts) {
beginResetModel();
m_posts.clear();
for (const auto& post : posts) {
m_posts.push_back(post);
}
endResetModel();
}
int ForumModel::rowCount(const QModelIndex &parent) const{
if (parent.isValid()) {
return 0;
}
return m_posts.count();
}
int ForumModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return ModelColumn::COUNT;
}
QVariant ForumModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_posts.count())
return QVariant();
QSharedPointer<ForumPost> post = m_posts.at(index.row());
if(role == Qt::DisplayRole) {
switch(index.column()) {
case Title:
return post->title;
case Author:
return post->author;
case Comments:
return QString::number(post->comments);
default:
return QVariant();
}
}
else if (role == Qt::TextAlignmentRole) {
switch(index.column()) {
case Comments:
return Qt::AlignRight;
default:
return QVariant();
}
}
return QVariant();
}
QVariant ForumModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole) {
return QVariant();
}
if (orientation == Qt::Horizontal)
{
switch(section) {
case Title:
return QString("Forum Post");
case Author:
return QString("Author");
case Comments:
return QString("Comments");
default:
return QVariant();
}
}
return QVariant();
}
QSharedPointer<ForumPost> ForumModel::post(int row) {
if (row < 0 || row >= m_posts.size()) {
qCritical("%s: no forum post for index %d", __FUNCTION__, row);
return QSharedPointer<ForumPost>();
}
return m_posts.at(row);
}
+41
View File
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef WOWLET_FORUMMODEL_H
#define WOWLET_FORUMMODEL_H
#include <QAbstractTableModel>
#include <QSharedPointer>
#include "widgets/ForumPost.h"
class ForumModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum ModelColumn
{
Title = 0,
Author,
Comments,
COUNT
};
explicit ForumModel(QObject *parent);
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
void clear();
void updatePosts(const QList<QSharedPointer<ForumPost>>& posts);
QSharedPointer<ForumPost> post(int row);
private:
QList<QSharedPointer<ForumPost>> m_posts;
};
#endif //WOWLET_FORUMMODEL_H
+1
View File
@@ -16,5 +16,6 @@ target_include_directories(openpgp PUBLIC
target_link_libraries(openpgp
PUBLIC
epee
${GCRYPT_LIBRARY}
${GPG_ERROR_LIBRARY})
-2
View File
@@ -64,8 +64,6 @@ void SendWidget::addressEdited() {
if (outputs.size() > 0) {
ui->lineAmount->setText(WalletManager::displayAmount(ui->lineAddress->getTotal()));
ui->comboCurrencySelection->setCurrentIndex(0);
} else {
ui->lineAmount->setText("");
}
ui->btn_openAlias->setVisible(ui->lineAddress->isOpenAlias());
+7
View File
@@ -21,6 +21,10 @@ Settings::Settings(QWidget *parent) :
connect(ui->btnCopyToClipboard, &QPushButton::clicked, this, &Settings::copyToClipboard);
connect(ui->checkBox_externalLink, &QCheckBox::clicked, this, &Settings::checkboxExternalLinkWarn);
connect(ui->checkBox_hideFiatBalance, &QCheckBox::toggled, [this](bool toggled){
config()->set(Config::hideFiatBalance, toggled);
m_ctx->updateBalance();
});
connect(ui->checkBox_hideBalance, &QCheckBox::toggled, [this](bool toggled){
config()->set(Config::hideBalance, toggled);
m_ctx->updateBalance();
@@ -47,6 +51,9 @@ Settings::Settings(QWidget *parent) :
connect(ui->comboBox_blockExplorer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_blockExplorerChanged);
connect(ui->comboBox_redditFrontend, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_redditFrontendChanged);
// setup reddit combobox
ui->comboBox_redditFrontend->setCurrentText(config()->get(Config::redditFrontend).toString());
// setup preferred fiat currency combobox
QStringList fiatCurrencies;
for (int index = 0; index < ui->comboBox_fiatCurrency->count(); index++)
+8 -1
View File
@@ -161,7 +161,7 @@
<item row="5" column="0">
<widget class="QCheckBox" name="checkBox_hideBalance">
<property name="text">
<string>Hide balance</string>
<string>Hide balances</string>
</property>
</widget>
</item>
@@ -191,6 +191,13 @@
</item>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_hideFiatBalance">
<property name="text">
<string>Hide fiat balance</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_node">
+5 -2
View File
@@ -22,7 +22,7 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::warnOnStagenet,{QS("warnOnStagenet"), true}},
{Config::warnOnTestnet,{QS("warnOnTestnet"), true}},
{Config::warnOnAlpha,{QS("warnOnAlpha"), true}},
{Config::homeWidget,{QS("homeWidget"), "ccs"}},
{Config::homeWidget,{QS("homeWidget"), 0}},
{Config::donateBeg,{QS("donateBeg"), 1}},
{Config::skin,{QS("skin"), "light"}},
{Config::openVRSkin,{QS("openVRSkin"), "default"}},
@@ -46,8 +46,11 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::windowState, {QS("windowState"), {}}},
{Config::firstRun,{QS("firstRun"), false}},
{Config::hideBalance, {QS("hideBalance"), false}},
{Config::hideFiatBalance, {QS("hideFiatBalance"), false}},
{Config::redditFrontend, {QS("redditFrontend"), "old.reddit.com"}},
{Config::showHistorySyncNotice, {QS("showHistorySyncNotice"), true}}
{Config::showHistorySyncNotice, {QS("showHistorySyncNotice"), true}},
{Config::ignoreUpdateWarning, {QS("ignoreUpdateWarning"), ""}},
{Config::suchWowTipAmount, {QS("suchWowTipAmount"), 0.75}}
};
+4 -1
View File
@@ -48,8 +48,11 @@ public:
windowState,
firstRun,
hideBalance,
hideFiatBalance,
redditFrontend,
showHistorySyncNotice
showHistorySyncNotice,
ignoreUpdateWarning,
suchWowTipAmount
};
~Config() override;
+5
View File
@@ -16,6 +16,7 @@ void UtilsNetworking::setUserAgent(const QString &userAgent) {
}
void UtilsNetworking::get(const QString &url) {
busy = true;
QNetworkRequest request;
request.setUrl(QUrl(url));
request.setRawHeader("User-Agent", m_userAgent.toUtf8());
@@ -26,6 +27,7 @@ void UtilsNetworking::get(const QString &url) {
}
QNetworkReply* UtilsNetworking::getJson(const QString &url) {
busy = true;
QNetworkRequest request;
request.setUrl(QUrl(url));
request.setRawHeader("User-Agent", m_userAgent.toUtf8());
@@ -35,6 +37,7 @@ QNetworkReply* UtilsNetworking::getJson(const QString &url) {
}
QNetworkReply* UtilsNetworking::postJson(const QString &url, const QJsonObject &data) {
busy = true;
QNetworkRequest request;
request.setUrl(QUrl(url));
request.setRawHeader("User-Agent", m_userAgent.toUtf8());
@@ -61,6 +64,8 @@ void UtilsNetworking::webResponse(QNetworkReply *reply) {
emit webErrorReceived(err);
else
emit webReceived(data);
busy = false;
}
QString UtilsNetworking::validateJSON(QNetworkReply *reply){
+2
View File
@@ -26,6 +26,8 @@ public:
void setUserAgent(const QString &userAgent);
static QString validateJSON(QNetworkReply *reply);
bool busy = false;
private slots:
void webResponse(QNetworkReply *reply);
+3 -1
View File
@@ -41,7 +41,9 @@ void Prices::cryptoPricesReceived(const QJsonArray &data) {
ms.symbol = obj.value("symbol").toString().toUpper();
ms.image = obj.value("image").toString();
ms.name = obj.value("name").toString();
ms.price_usd = obj.value("current_price").toDouble();
ms.price_usd = obj.value("current_price").toDouble(0);
ms.price_btc = obj.value("current_price_btc").toDouble(0.0);
ms.price_sat = obj.value("current_price_satoshi").toInt(0);
ms.price_usd_change_pct_24h = obj.value("price_change_percentage_24h").toDouble();
if(ms.price_usd <= 0) continue;
+2
View File
@@ -15,6 +15,8 @@ struct marketStruct {
QString name;
QString image;
double price_usd;
double price_btc;
uint price_sat;
double price_usd_change_pct_24h;
};
+38 -2
View File
@@ -256,11 +256,14 @@ QStandardItem *Utils::qStandardItem(const QString& text, QFont &font) {
}
QString Utils::getUnixAccountName() {
#ifdef __ANDROID__
return "";
#endif
QString accountName = qgetenv("USER"); // mac/linux
if (accountName.isEmpty())
accountName = qgetenv("USERNAME"); // Windows
if (accountName.isEmpty())
throw std::runtime_error("Could derive system account name from env vars: USER or USERNAME");
throw std::runtime_error("Could not derive system account name from env vars: USER or USERNAME");
return accountName;
}
@@ -431,6 +434,16 @@ int Utils::maxLength(const QVector<QString> &array) {
return maxLength;
}
bool Utils::versionOutdated(const QString &current_version, const QString &newest_version) {
// True when major or minor version changed
auto cver = current_version.split('.');
auto nver = newest_version.split('.');
int cverlist[] = {cver.at(0).toInt(), cver.at(1).toInt()};
int nverlist[] = {nver.at(0).toInt(), nver.at(1).toInt()};
if(cverlist[0] < nverlist[0] || cverlist[1] < nverlist[1]) return true;
return false;
}
QString Utils::balanceFormat(quint64 balance) {
QString str = QString::number(balance / globals::cdiv, 'f', 4);
@@ -454,4 +467,27 @@ QTextCharFormat Utils::addressTextFormat(const SubaddressIndex &index) {
return rec;
}
return QTextCharFormat();
}
}
#ifdef __ANDROID__
bool Utils::androidAskPermissions(const QVector<QString> &permissions) {
bool rtn = true;
if(QtAndroid::androidSdkVersion() >= 23) {
for(const QString &permission : permissions) {
auto result = QtAndroid::checkPermission(permission);
if(result != QtAndroid::PermissionResult::Granted) {
auto resultHash = QtAndroid::requestPermissionsSync(QStringList({permission}));
if(resultHash[permission] != QtAndroid::PermissionResult::Granted) {
qDebug() << "Fail to get permission" << permission;
rtn = false;
} else {
qDebug() << "Permission" << permission << "granted!";
}
} else {
qDebug() << "Permission" << permission << "already granted!";
}
}
}
return rtn;
}
#endif
+9 -2
View File
@@ -8,6 +8,9 @@
#include <QStandardItemModel>
#include <QApplication>
#include <QTextCharFormat>
#ifdef __ANDROID__
#include <QtAndroid>
#endif
#include <monero_seed/monero_seed.hpp>
@@ -78,12 +81,16 @@ public:
static QMap<QString, QLocale> localeCache;
static QString balanceFormat(quint64 balance);
static QTextCharFormat addressTextFormat(const SubaddressIndex &index);
static bool versionOutdated(const QString &current_version, const QString &newest_version);
template<typename QEnum>
static QString QtEnumToString (const QEnum value)
{
static QString QtEnumToString (const QEnum value) {
return QString::fromStdString(std::string(QMetaEnum::fromType<QEnum>().valueToKey(value)));
}
#ifdef __ANDROID__
static bool androidAskPermissions(const QVector<QString> &permissions);
#endif
};
class AppContext; // forward declaration
+14 -12
View File
@@ -184,31 +184,33 @@ namespace wowletvr {
auto results = m_qrDecoder.decodePNG(path);
auto result = wowletvr::WowletVR::checkQRScreenshotResults(results);
qDebug() << "no initial results";
qDebug() << "QR code try #1: " << result;
if(result.isEmpty()) {
qDebug() << "trying to invert the image";
// lets try to invert the image
QImage image(path);
image.invertPixels();
image.save(pathPreview);
results = m_qrDecoder.decodePNG(pathPreview);
result = wowletvr::WowletVR::checkQRScreenshotResults(results);
if(!result.isEmpty()) {
qDebug() << "Found QR code after inverting the image.";
qDebug() << "QR code try #2: " << result;
}
if(!result.isEmpty()) {
qDebug() << "QR code decoded, trying address validation.";
if(result.toLower().startsWith("wownero:"))
result = result.remove(0, 8);
if(WalletManager::addressValid(result, NetworkType::MAINNET)) {
qDebug() << "QR code appears valid.";
emit qrScreenshotSuccess(result);
QFile file (path);
QFile file(path);
file.remove();
return;
}
} else {
qDebug() << "QR code found.";
emit qrScreenshotSuccess(result);
QFile file (path);
file.remove();
return;
}
emit qrScreenshotSuccess("No QR code could be detected.");
emit qrScreenshotFailed("No QR code could be detected.");
}
QString WowletVR::checkQRScreenshotResults(std::vector<std::string> results) {
+1 -5
View File
@@ -51,13 +51,9 @@ ColumnLayout {
function onQrScreenshotSuccess(address) {
root.takingScreenshot = false;
console.log("onPinLookupReceived", address);
if(!address.startsWith("wownero:")) {
messagePopup.showMessage("Invalid QR code", "QR data did not start with \"wownero:\"");
return;
}
if(sendStateView.currentView === sendStateView.qrPage) {
sendStateController.destinationAddress = address.slice(8);
sendStateController.destinationAddress = address;
sendStateView.state = "transferPage";
}
}

Some files were not shown because too many files have changed in this diff Show More