summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml53
-rw-r--r--.travis.yml99
-rw-r--r--AppImageBuilder.yml122
-rw-r--r--src/Cache.cpp39
-rw-r--r--src/MainWindow.cpp4
-rw-r--r--src/UserSettingsPage.cpp34
-rw-r--r--src/UserSettingsPage.h9
-rw-r--r--src/main.cpp14
8 files changed, 242 insertions, 132 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2ecfa17c..8a6775db 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -143,3 +143,56 @@ linting:
     - apk update && apk add clang make git
   script:
     - make lint
+
+appimage-amd64:
+  stage: build
+  image: appimagecrafters/appimage-builder
+  tags: [docker]
+  before_script:
+    # app build requirements
+    - echo 'deb http://archive.neon.kde.org/user/ bionic main' > /etc/apt/sources.list.d/neon.list
+    - wget -qO - https://archive.neon.kde.org/public.key | apt-key add -
+    - apt-get update
+    - apt-get install -y git wget curl
+
+    # update appimage-builder (optional)
+    - pip3 install --upgrade git+https://www.opencode.net/azubieta/appimagecraft.git
+
+    - apt-get install -y qt5-default qtdeclarative5-dev qttools5-dev qtscript5-dev qtquickcontrols2-5-dev qtmultimedia5-dev libqt5svg5-dev liblmdb-dev libssl-dev git ninja-build qt5keychain-dev libgtest-dev ccache
+    - wget https://github.com/Kitware/CMake/releases/download/v3.19.0/cmake-3.19.0-Linux-x86_64.sh && sh cmake-3.19.0-Linux-x86_64.sh  --skip-license  --prefix=/usr/local
+    - /usr/sbin/update-ccache-symlinks
+  script:
+    - export PATH="/usr/local/bin/:/usr/lib/ccache:${PATH}"
+    - export CMAKE_BUILD_PARALLEL_LEVEL=$(cat /proc/cpuinfo | awk '/^processor/{print $3}' | wc -l)
+    - cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -GNinja
+      -DHUNTER_ROOT=".hunter"
+      -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF
+      -DHUNTER_CONFIGURATION_TYPES=Release
+      -DUSE_BUNDLED_BOOST=ON
+      -DUSE_BUNDLED_SPDLOG=ON
+      -DUSE_BUNDLED_OLM=ON
+      -DUSE_BUNDLED_GTEST=OFF
+      -DUSE_BUNDLED_CMARK=ON
+      -DUSE_BUNDLED_JSON=ON
+      -DUSE_BUNDLED_OPENSSL=OFF
+      -DUSE_BUNDLED_MTXCLIENT=ON
+      -DUSE_BUNDLED_LMDB=OFF
+      -DUSE_BUNDLED_LMDBXX=ON
+      -DUSE_BUNDLED_TWEENY=ON
+      -DUSE_BUNDLED_QTKEYCHAIN=OFF
+    - DESTDIR=`pwd`/AppDir ninja -C build install/local
+    - DESTDIR=`pwd`/AppDir ninja -C build _deps/cmark-build/src/install
+    - mkdir -p AppDir/usr/lib/x86_64-linux-gnu AppDir/lib/x86_64-linux-gnu
+    - appimage-builder --skip-test
+  after_script:
+    - bash ./.ci/upload-nightly-gitlab.sh nheko-latest-x86_64.AppImage
+  artifacts:
+    paths:
+      - 'nheko-latest-x86_64.AppImage'
+    expire_in: 1 week
+    expose_as: 'appimage-amd64'
+  cache:
+    key: "$CI_JOB_NAME"
+    paths:
+      - .hunter/
+      - .ccache
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 935e7c6f..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,99 +0,0 @@
-language: cpp
-sudo: required
-dist: xenial
-
-notifications:
-  webhooks:
-    urls:
-    - https://scalar.vector.im/api/neb/services/hooks/dHJhdmlzLWNpLyU0MHJlZF9za3klM0FuaGVrby5pbS8lMjFVYkNtSWxHVEhOSWdJUlpjcHQlM0FuaGVrby5pbQ
-    on_success: always
-    on_failure: always
-    on_start: never
-  email: false
-
-cache:
-  directories:
-    - .hunter
-
-matrix:
-    include:
-        - os: linux
-          compiler: gcc-7
-          env:
-              - CXX=g++-7
-              - CC=gcc-7
-              - QT_PKG=512
-              - DEPLOYMENT=1
-          addons:
-              apt:
-                  sources: 
-                    - ubuntu-toolchain-r-test
-                    - sourceline: 'ppa:beineri/opt-qt-5.12.6-xenial'
-                  packages: 
-                    - g++-7 
-                    - ninja-build
-                    - qt512base
-                    - qt512tools
-                    - qt512svg
-                    - qt512multimedia
-                    - qt512quickcontrols2
-                    - qt512graphicaleffects
-                    - liblmdb-dev
-                    - libgl1-mesa-dev # needed for missing gl.h
-        - os: linux
-          compiler: clang-6
-          env:
-              - CXX=clang++-6.0
-              - CC=clang-6.0
-              - QT_PKG=510
-          addons:
-              apt:
-                  sources: 
-                    - ubuntu-toolchain-r-test
-                    - llvm-toolchain-xenial-6.0
-                    - sourceline: 'ppa:beineri/opt-qt-5.10.1-xenial'
-                  packages: 
-                    - clang++-6.0
-                    - g++-7 
-                    - ninja-build
-                    - qt510base
-                    - qt510tools
-                    - qt510svg
-                    - qt510multimedia
-                    - qt510quickcontrols2
-                    - qt510graphicaleffects
-                    - liblmdb-dev
-                    - libgl1-mesa-dev # needed for missing gl.h
-
-before_install:
-    # Use TRAVIS_TAG if defined, or the short commit SHA otherwise
-    - export VERSION=${TRAVIS_TAG:-$(git rev-parse --short HEAD)}
-install:
-    - ./.ci/install.sh
-    - export PATH=/usr/local/bin:${PATH}
-
-script:
-    - ./.ci/script.sh
-    - sed -i -e "s/VERSION_NAME_VALUE/${VERSION}/g" ./.ci/bintray-release.json || true
-    - cp ./.ci/bintray-release.json .
-deploy:
-- provider: script
-  script: ./.ci/upload-nightly.sh
-  skip_cleanup: true
-  on:
-    condition: "$DEPLOYMENT == 1"
-    repo: Nheko-Reborn/nheko
-    tags: false
-    all_branches: true
-- skip_cleanup: true
-  overwrite: true
-  provider: releases
-  api_key:
-    secure: "rDFG4DIwIG+A9R8seQ3SIXfWOWhJgJHlNQHtAsnfRrPOSIpI7kMebHLDO5sBPNaJ+9MH9acVTJZOabVLf0DdPqRsDUw/PN28aiiqbaH9+zAGOTxahaQ222Gz/ROf/iXvDoTDUnUzURqQUA0YlHy89Z1CnO7TKwlsYhA5A8n0biG7d8i7vQayvwYXfxlk7CouK+Y86ana4r54j1emGRg97p7BOhORibg54ZD520hN0Iif7EJM2hQDTWKZzTDdBt3mF1kBr7cBbuBHWuvE+eIFO3F3yi+u7ggHzw5FaAv245N4fhkpYUl/mSbhLrQG2NOnkglFCpQ2lLd6mWdXHwUNrxN/j+UPewmLg7CymY25zkiL43deDsT8KmpzYalmdaevCqEaX2VehuBzblmH4Re8wnXqBrab14fq0TNDfPqC+NKxy75mdxszbKBC55nTlTB+hsox43dvfvyXDSON4qAzwe9Q/tfp8mL2mehcM868vhw5cbNIskKT8SrhMwmA+sxoqnqLsmAjNVJVTgg6ppbMhjNMOBTndblRHfH6bxsgpTXPtnzC17o9Mw1WgF63eOWNYBEj2wW5ZvWX95Gvg5YzvsF178ipHZDqZfA62ShB3b89fcqN5SOxBsE8UYoHjQIHxQdWeKv23iFwmT8fWAOD8sKDcRyz0WCgidZ1/RjLqsU="
-  file_glob: true
-  file:
-  - nheko-${VERSION}-x86_64.AppImage
-  on:
-    condition: "$TRAVIS_OS_NAME == linux && $DEPLOYMENT == 1"
-    repo: Nheko-Reborn/nheko
-    tags: true
diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml
new file mode 100644
index 00000000..7b263058
--- /dev/null
+++ b/AppImageBuilder.yml
@@ -0,0 +1,122 @@
+# appimage-builder recipe see https://appimage-builder.readthedocs.io for details
+version: 1
+AppDir:
+  path: ./AppDir
+  app_info:
+    id: nheko
+    name: nheko
+    icon: nheko
+    version: latest
+    exec: usr/bin/nheko
+    exec_args: $@
+  runtime:
+    env:
+      APPDIR_LIBRARY_PATH: $APPDIR/usr/lib/x86_64-linux-gnu:$APPDIR/usr/lib/x86_64-linux-gnu/gstreamer-1.0:$APPDIR/usr/lib/x86_64-linux-gnu/gconv:$APPDIR/lib/x86_64-linux-gnu:$APPDIR/usr/lib/x86_64-linux-gnu/pulseaudio
+  apt:
+    arch: amd64
+    allow_unauthenticated: true
+    sources:
+    - sourceline: deb http://de.archive.ubuntu.com/ubuntu/ bionic main restricted
+    - sourceline: deb http://de.archive.ubuntu.com/ubuntu/ bionic-updates main restricted
+    - sourceline: deb http://de.archive.ubuntu.com/ubuntu/ bionic universe
+    - sourceline: deb http://de.archive.ubuntu.com/ubuntu/ bionic-updates universe
+    - sourceline: deb http://de.archive.ubuntu.com/ubuntu/ bionic multiverse
+    - sourceline: deb http://de.archive.ubuntu.com/ubuntu/ bionic-updates multiverse
+    - sourceline: deb http://de.archive.ubuntu.com/ubuntu/ bionic-backports main restricted
+        universe multiverse
+    - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security main restricted
+    - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security universe
+    - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security multiverse
+    - sourceline: deb http://archive.neon.kde.org/user/ bionic main
+    include:
+    - gstreamer1.0-libav
+    - gstreamer1.0-plugins-bad
+    - gstreamer1.0-plugins-base
+    - gstreamer1.0-plugins-good
+    - gstreamer1.0-pulseaudio
+    - gstreamer1.0-x
+    - kimageformat-plugins
+    - libbs2b0
+    - libbz2-1.0
+    - libelf1
+    - libexpat1
+    - libhogweed4
+    - libjpeg-turbo8
+    - libkf5archive5
+    - libllvm10
+    - liblmdb0
+    - liblz4-1
+    - libnorm1
+    - libnss-mdns
+    - libopenexr22
+    - libpcre3
+    - libqt5keychain1
+    - libqt5multimedia5-plugins
+    - libqt5multimediagsttools5
+    - libqt5multimediawidgets5
+    - libqt5quickcontrols2-5
+    - libqt5quicktemplates2-5
+    - libqt5quickwidgets5
+    - libqt5svg5
+    - librubberband2
+    - libsensors4
+    - libsm6
+    - libsnappy1v5
+    - libsystemd0
+    - libwayland-server0
+    - libx264-152
+    - libxau6
+    - libxcb-render-util0
+    - libxcb-sync1
+    - libxcb-xinerama0
+    - libxcb-xkb1
+    - libxcursor1
+    - libxdmcp6
+    - libxext6
+    - libxfixes3
+    - libxrender1
+    - libxshmfence1
+    - libxv1
+    - libxxf86vm1
+    - libzstd1
+    - qml-module-qtgraphicaleffects
+    - qml-module-qtmultimedia
+    - qml-module-qtquick-controls2
+    - qml-module-qtquick-layouts
+    - qml-module-qtquick-templates2
+    - qml-module-qtquick-window2
+    - qml-module-qtquick2
+    - qt5-image-formats-plugins
+    exclude: []
+  files:
+    exclude:
+    - usr/share/man
+    - usr/share/doc/*/README.*
+    - usr/share/doc/*/changelog.*
+    - usr/share/doc/*/NEWS.*
+    - usr/share/doc/*/TODO.*
+  test:
+    fedora:
+      image: appimagecrafters/tests-env:fedora-30
+      command: ./AppRun
+      use_host_x: true
+    debian:
+      image: appimagecrafters/tests-env:debian-stable
+      command: ./AppRun
+      use_host_x: true
+    arch:
+      image: appimagecrafters/tests-env:archlinux-latest
+      command: ./AppRun
+      use_host_x: true
+    centos:
+      image: appimagecrafters/tests-env:centos-7
+      command: ./AppRun
+      use_host_x: true
+    ubuntu:
+      image: appimagecrafters/tests-env:ubuntu-xenial
+      command: ./AppRun
+      use_host_x: true
+AppImage:
+  arch: x86_64
+  update-information: None
+  sign-key: None
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 5d11a178..dac0b23a 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -167,13 +167,14 @@ Cache::Cache(const QString &userId, QObject *parent)
 void
 Cache::setup()
 {
-        UserSettings settings;
+        auto settings = UserSettings::instance();
 
         nhlog::db()->debug("setting up cache");
 
         cacheDirectory_ = QString("%1/%2%3")
                             .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
-                            .arg(QString::fromUtf8(localUserId_.toUtf8().toHex())).arg(QString::fromUtf8(settings.profile().toUtf8().toHex()));
+                            .arg(QString::fromUtf8(localUserId_.toUtf8().toHex()))
+                            .arg(QString::fromUtf8(settings->profile().toUtf8().toHex()));
 
         bool isInitial = !QFile::exists(cacheDirectory_);
 
@@ -186,7 +187,9 @@ Cache::setup()
 
                 if (!QDir().mkpath(cacheDirectory_)) {
                         throw std::runtime_error(
-                          ("Unable to create state directory:" + cacheDirectory_).toStdString().c_str());
+                          ("Unable to create state directory:" + cacheDirectory_)
+                            .toStdString()
+                            .c_str());
                 }
         }
 
@@ -575,14 +578,14 @@ Cache::restoreOlmAccount()
 void
 Cache::storeSecret(const std::string &name, const std::string &secret)
 {
-      UserSettings settings;
+        auto settings = UserSettings::instance();
         QKeychain::WritePasswordJob job(QCoreApplication::applicationName());
         job.setAutoDelete(false);
         job.setInsecureFallback(true);
-        job.setKey(
-          "matrix." +
-          QString(QCryptographicHash::hash(settings.profile().toUtf8(), QCryptographicHash::Sha256)) +
-          "." + name.c_str());
+        job.setKey("matrix." +
+                   QString(QCryptographicHash::hash(settings->profile().toUtf8(),
+                                                    QCryptographicHash::Sha256)) +
+                   "." + name.c_str());
         job.setTextData(QString::fromStdString(secret));
         QEventLoop loop;
         job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
@@ -600,14 +603,14 @@ Cache::storeSecret(const std::string &name, const std::string &secret)
 void
 Cache::deleteSecret(const std::string &name)
 {
-        UserSettings settings;
+        auto settings = UserSettings::instance();
         QKeychain::DeletePasswordJob job(QCoreApplication::applicationName());
         job.setAutoDelete(false);
         job.setInsecureFallback(true);
-        job.setKey(
-          "matrix." +
-          QString(QCryptographicHash::hash(settings.profile().toUtf8(), QCryptographicHash::Sha256)) +
-          "." + name.c_str());
+        job.setKey("matrix." +
+                   QString(QCryptographicHash::hash(settings->profile().toUtf8(),
+                                                    QCryptographicHash::Sha256)) +
+                   "." + name.c_str());
         QEventLoop loop;
         job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
         job.start();
@@ -619,14 +622,14 @@ Cache::deleteSecret(const std::string &name)
 std::optional<std::string>
 Cache::secret(const std::string &name)
 {
-        UserSettings settings;
+        auto settings = UserSettings::instance();
         QKeychain::ReadPasswordJob job(QCoreApplication::applicationName());
         job.setAutoDelete(false);
         job.setInsecureFallback(true);
-        job.setKey(
-          "matrix." +
-          QString(QCryptographicHash::hash(settings.profile().toUtf8(), QCryptographicHash::Sha256)) +
-          "." + name.c_str());
+        job.setKey("matrix." +
+                   QString(QCryptographicHash::hash(settings->profile().toUtf8(),
+                                                    QCryptographicHash::Sha256)) +
+                   "." + name.c_str());
         QEventLoop loop;
         job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
         job.start();
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index bc7b5223..77269008 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -56,8 +56,8 @@
 MainWindow *MainWindow::instance_ = nullptr;
 
 MainWindow::MainWindow(QWidget *parent)
-  : QMainWindow(parent),
-    userSettings_{QSharedPointer<UserSettings>{new UserSettings}}
+  : QMainWindow(parent)
+  , userSettings_{UserSettings::instance()}
 {
         setWindowTitle(0);
         setObjectName("MainWindow");
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index 55f666c1..4ca3be49 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -50,10 +50,30 @@
 
 #include "config/nheko.h"
 
-UserSettings::UserSettings() { load(); }
+QSharedPointer<UserSettings> UserSettings::instance_;
+
+UserSettings::UserSettings()
+{
+        connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, [this]() {
+                instance_.clear();
+        });
+}
+
+QSharedPointer<UserSettings>
+UserSettings::instance()
+{
+        return instance_;
+}
+
+void
+UserSettings::initialize(std::optional<QString> profile)
+{
+        instance_.reset(new UserSettings());
+        instance_->load(profile);
+}
 
 void
-UserSettings::load()
+UserSettings::load(std::optional<QString> profile)
 {
         QSettings settings;
         tray_                    = settings.value("user/window/tray", false).toBool();
@@ -89,7 +109,11 @@ UserSettings::load()
         cameraResolution_ = settings.value("user/camera_resolution", QString()).toString();
         cameraFrameRate_  = settings.value("user/camera_frame_rate", QString()).toString();
         useStunServer_    = settings.value("user/use_stun_server", false).toBool();
-        profile_          = settings.value("user/currentProfile", "").toString();
+
+        if (profile)
+                profile_ = *profile;
+        else
+                profile_ = settings.value("user/currentProfile", "").toString();
 
         QString prefix =
           (profile_ != "" && profile_ != "default") ? "profile/" + profile_ + "/" : "";
@@ -527,6 +551,8 @@ UserSettings::save()
         settings.setValue("use_stun_server", useStunServer_);
         settings.setValue("currentProfile", profile_);
 
+        settings.endGroup(); // user
+
         QString prefix =
           (profile_ != "" && profile_ != "default") ? "profile/" + profile_ + "/" : "";
         settings.setValue(prefix + "auth/access_token", accessToken_);
@@ -534,8 +560,6 @@ UserSettings::save()
         settings.setValue(prefix + "auth/user_id", userId_);
         settings.setValue(prefix + "auth/device_id", deviceId_);
 
-        settings.endGroup(); // user
-
         settings.sync();
 }
 
diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index dd1e26d9..af73202e 100644
--- a/src/UserSettingsPage.h
+++ b/src/UserSettingsPage.h
@@ -91,9 +91,12 @@ class UserSettings : public QObject
         Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
         Q_PROPERTY(QString homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged)
 
-public:
         UserSettings();
 
+public:
+        static QSharedPointer<UserSettings> instance();
+        static void initialize(std::optional<QString> profile);
+
         enum class Presence
         {
                 AutomaticPresence,
@@ -104,7 +107,7 @@ public:
         Q_ENUM(Presence)
 
         void save();
-        void load();
+        void load(std::optional<QString> profile);
         void applyTheme();
         void setTheme(QString theme);
         void setMessageHoverHighlight(bool state);
@@ -252,6 +255,8 @@ private:
         QString accessToken_;
         QString deviceId_;
         QString homeserver_;
+
+        static QSharedPointer<UserSettings> instance_;
 };
 
 class HorizontalLine : public QFrame
diff --git a/src/main.cpp b/src/main.cpp
index 58bdda34..a60c66c4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -196,17 +196,19 @@ main(int argc, char *argv[])
                 std::exit(1);
         }
 
-        UserSettings settings;
-
         if (parser.isSet(configName))
-                settings.setProfile(parser.value(configName));
+                UserSettings::initialize(parser.value(configName));
+        else
+                UserSettings::initialize(std::nullopt);
+
+        auto settings = UserSettings::instance().toWeakRef();
 
         QFont font;
-        QString userFontFamily = settings.font();
+        QString userFontFamily = settings.lock()->font();
         if (!userFontFamily.isEmpty()) {
                 font.setFamily(userFontFamily);
         }
-        font.setPointSizeF(settings.fontSize());
+        font.setPointSizeF(settings.lock()->fontSize());
 
         app.setFont(font);
 
@@ -226,7 +228,7 @@ main(int argc, char *argv[])
         // Move the MainWindow to the center
         w.move(screenCenter(w.width(), w.height()));
 
-        if (!settings.startInTray() && !settings.tray())
+        if (!settings.lock()->startInTray() && !settings.lock()->tray())
                 w.show();
 
         QObject::connect(&app, &QApplication::aboutToQuit, &w, [&w]() {