diff --git a/src/Cache.cpp b/src/Cache.cpp
index d9db99b0..993fbfe7 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -2280,34 +2280,22 @@ Cache::joinedRooms()
return room_ids;
}
-void
-Cache::populateMembers()
+std::optional<MemberInfo>
+Cache::getMember(const std::string &room_id, const std::string &user_id)
{
- auto rooms = joinedRooms();
- nhlog::db()->info("loading {} rooms", rooms.size());
-
- auto txn = lmdb::txn::begin(env_);
-
- for (const auto &room : rooms) {
- const auto roomid = QString::fromStdString(room);
-
- auto membersdb = getMembersDb(txn, room);
- auto cursor = lmdb::cursor::open(txn, membersdb);
-
- std::string user_id, info;
- while (cursor.get(user_id, info, MDB_NEXT)) {
- MemberInfo m = json::parse(info);
+ try {
+ auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
- const auto userid = QString::fromStdString(user_id);
+ auto membersdb = getMembersDb(txn, room_id);
- insertDisplayName(roomid, userid, QString::fromStdString(m.name));
- insertAvatarUrl(roomid, userid, QString::fromStdString(m.avatar_url));
+ lmdb::val info;
+ if (lmdb::dbi_get(txn, membersdb, lmdb::val(user_id), info)) {
+ MemberInfo m = json::parse(std::string_view(info.data(), info.size()));
+ return m;
}
-
- cursor.close();
+ } catch (...) {
}
-
- txn.commit();
+ return std::nullopt;
}
std::vector<RoomSearchResult>
@@ -2724,8 +2712,19 @@ Cache::saveOldMessages(const std::string &room_id, const mtx::responses::Message
}
}
- if (res.chunk.empty())
+ if (res.chunk.empty()) {
+ if (lmdb::dbi_get(txn, orderDb, lmdb::val(&index, sizeof(index)), val)) {
+ auto orderEntry = json::parse(std::string_view(val.data(), val.size()));
+ orderEntry["prev_batch"] = res.end;
+ lmdb::dbi_put(txn,
+ orderDb,
+ lmdb::val(&index, sizeof(index)),
+ lmdb::val(orderEntry.dump()));
+ nhlog::db()->debug("saving '{}'", orderEntry.dump());
+ txn.commit();
+ }
return index;
+ }
std::string event_id_val;
for (const auto &e : res.chunk) {
@@ -3145,15 +3144,12 @@ Cache::roomMembers(const std::string &room_id)
return members;
}
-QHash<QString, QString> Cache::DisplayNames;
-QHash<QString, QString> Cache::AvatarUrls;
-
QString
Cache::displayName(const QString &room_id, const QString &user_id)
{
- auto fmt = QString("%1 %2").arg(room_id).arg(user_id);
- if (DisplayNames.contains(fmt))
- return DisplayNames[fmt];
+ if (auto info = getMember(room_id.toStdString(), user_id.toStdString());
+ info && !info->name.empty())
+ return QString::fromStdString(info->name);
return user_id;
}
@@ -3161,9 +3157,8 @@ Cache::displayName(const QString &room_id, const QString &user_id)
std::string
Cache::displayName(const std::string &room_id, const std::string &user_id)
{
- auto fmt = QString::fromStdString(room_id + " " + user_id);
- if (DisplayNames.contains(fmt))
- return DisplayNames[fmt].toStdString();
+ if (auto info = getMember(room_id, user_id); info && !info->name.empty())
+ return info->name;
return user_id;
}
@@ -3171,41 +3166,11 @@ Cache::displayName(const std::string &room_id, const std::string &user_id)
QString
Cache::avatarUrl(const QString &room_id, const QString &user_id)
{
- auto fmt = QString("%1 %2").arg(room_id).arg(user_id);
- if (AvatarUrls.contains(fmt))
- return AvatarUrls[fmt];
-
- return QString();
-}
-
-void
-Cache::insertDisplayName(const QString &room_id,
- const QString &user_id,
- const QString &display_name)
-{
- auto fmt = QString("%1 %2").arg(room_id).arg(user_id);
- DisplayNames.insert(fmt, display_name);
-}
-
-void
-Cache::removeDisplayName(const QString &room_id, const QString &user_id)
-{
- auto fmt = QString("%1 %2").arg(room_id).arg(user_id);
- DisplayNames.remove(fmt);
-}
-
-void
-Cache::insertAvatarUrl(const QString &room_id, const QString &user_id, const QString &avatar_url)
-{
- auto fmt = QString("%1 %2").arg(room_id).arg(user_id);
- AvatarUrls.insert(fmt, avatar_url);
-}
+ if (auto info = getMember(room_id.toStdString(), user_id.toStdString());
+ info && !info->avatar_url.empty())
+ return QString::fromStdString(info->avatar_url);
-void
-Cache::removeAvatarUrl(const QString &room_id, const QString &user_id)
-{
- auto fmt = QString("%1 %2").arg(room_id).arg(user_id);
- AvatarUrls.remove(fmt);
+ return "";
}
mtx::presence::PresenceState
@@ -3793,28 +3758,6 @@ avatarUrl(const QString &room_id, const QString &user_id)
return instance_->avatarUrl(room_id, user_id);
}
-void
-removeDisplayName(const QString &room_id, const QString &user_id)
-{
- instance_->removeDisplayName(room_id, user_id);
-}
-void
-removeAvatarUrl(const QString &room_id, const QString &user_id)
-{
- instance_->removeAvatarUrl(room_id, user_id);
-}
-
-void
-insertDisplayName(const QString &room_id, const QString &user_id, const QString &display_name)
-{
- instance_->insertDisplayName(room_id, user_id, display_name);
-}
-void
-insertAvatarUrl(const QString &room_id, const QString &user_id, const QString &avatar_url)
-{
- instance_->insertAvatarUrl(room_id, user_id, avatar_url);
-}
-
mtx::presence::PresenceState
presenceState(const std::string &user_id)
{
@@ -3826,13 +3769,6 @@ statusMessage(const std::string &user_id)
return instance_->statusMessage(user_id);
}
-//! Load saved data for the display names & avatars.
-void
-populateMembers()
-{
- instance_->populateMembers();
-}
-
// user cache stores user keys
std::optional<UserKeyCache>
userKeys(const std::string &user_id)
diff --git a/src/Cache.h b/src/Cache.h
index 24b6df9e..98e6cb75 100644
--- a/src/Cache.h
+++ b/src/Cache.h
@@ -44,16 +44,6 @@ displayName(const QString &room_id, const QString &user_id);
QString
avatarUrl(const QString &room_id, const QString &user_id);
-void
-removeDisplayName(const QString &room_id, const QString &user_id);
-void
-removeAvatarUrl(const QString &room_id, const QString &user_id);
-
-void
-insertDisplayName(const QString &room_id, const QString &user_id, const QString &display_name);
-void
-insertAvatarUrl(const QString &room_id, const QString &user_id, const QString &avatar_url);
-
// presence
mtx::presence::PresenceState
presenceState(const std::string &user_id);
@@ -74,9 +64,6 @@ markDeviceVerified(const std::string &user_id, const std::string &device);
void
markDeviceUnverified(const std::string &user_id, const std::string &device);
-//! Load saved data for the display names & avatars.
-void
-populateMembers();
std::vector<std::string>
joinedRooms();
diff --git a/src/Cache_p.h b/src/Cache_p.h
index 62b1ad37..a32793ea 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -46,9 +46,9 @@ class Cache : public QObject
public:
Cache(const QString &userId, QObject *parent = nullptr);
- static std::string displayName(const std::string &room_id, const std::string &user_id);
- static QString displayName(const QString &room_id, const QString &user_id);
- static QString avatarUrl(const QString &room_id, const QString &user_id);
+ std::string displayName(const std::string &room_id, const std::string &user_id);
+ QString displayName(const QString &room_id, const QString &user_id);
+ QString avatarUrl(const QString &room_id, const QString &user_id);
// presence
mtx::presence::PresenceState presenceState(const std::string &user_id);
@@ -71,18 +71,6 @@ public:
void markDeviceVerified(const std::string &user_id, const std::string &device);
void markDeviceUnverified(const std::string &user_id, const std::string &device);
- static void removeDisplayName(const QString &room_id, const QString &user_id);
- static void removeAvatarUrl(const QString &room_id, const QString &user_id);
-
- static void insertDisplayName(const QString &room_id,
- const QString &user_id,
- const QString &display_name);
- static void insertAvatarUrl(const QString &room_id,
- const QString &user_id,
- const QString &avatar_url);
-
- //! Load saved data for the display names & avatars.
- void populateMembers();
std::vector<std::string> joinedRooms();
QMap<QString, RoomInfo> roomInfo(bool withInvites = true);
@@ -308,6 +296,8 @@ private:
QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
+ std::optional<MemberInfo> getMember(const std::string &room_id, const std::string &user_id);
+
std::string getLastEventId(lmdb::txn &txn, const std::string &room_id);
DescInfo getLastMessageInfo(lmdb::txn &txn, const std::string &room_id);
void saveTimelineMessages(lmdb::txn &txn,
@@ -364,25 +354,12 @@ private:
lmdb::val(e->state_key),
lmdb::val(json(tmp).dump()));
- insertDisplayName(QString::fromStdString(room_id),
- QString::fromStdString(e->state_key),
- QString::fromStdString(display_name));
-
- insertAvatarUrl(QString::fromStdString(room_id),
- QString::fromStdString(e->state_key),
- QString::fromStdString(e->content.avatar_url));
-
break;
}
default: {
lmdb::dbi_del(
txn, membersdb, lmdb::val(e->state_key), lmdb::val(""));
- removeDisplayName(QString::fromStdString(room_id),
- QString::fromStdString(e->state_key));
- removeAvatarUrl(QString::fromStdString(room_id),
- QString::fromStdString(e->state_key));
-
break;
}
}
@@ -602,9 +579,6 @@ private:
QString localUserId_;
QString cacheDirectory_;
- static QHash<QString, QString> DisplayNames;
- static QHash<QString, QString> AvatarUrls;
-
OlmSessionStorage session_storage;
VerificationStorage verification_storage;
};
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 8b6f1123..235c5ea7 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -272,7 +272,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
connect(room_list_,
SIGNAL(totalUnreadMessageCountUpdated(int)),
this,
- SLOT(showUnreadMessageNotification(int)));
+ SIGNAL(unreadMessages(int)));
connect(text_input_,
&TextInputWidget::sendTextMessage,
@@ -626,7 +626,7 @@ ChatPage::resetUI()
user_info_widget_->reset();
view_manager_->clearAll();
- showUnreadMessageNotification(0);
+ emit unreadMessages(0);
}
void
@@ -752,18 +752,6 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
}
void
-ChatPage::showUnreadMessageNotification(int count)
-{
- emit unreadMessages(count);
-
- // TODO: Make the default title a const.
- if (count == 0)
- emit changeWindowTitle("nheko");
- else
- emit changeWindowTitle(QString("nheko (%1)").arg(count));
-}
-
-void
ChatPage::loadStateFromCache()
{
emit contentLoaded();
@@ -774,8 +762,6 @@ ChatPage::loadStateFromCache()
cache::restoreSessions();
olm::client()->load(cache::restoreOlmAccount(), STORAGE_SECRET_KEY);
- cache::populateMembers();
-
emit initializeEmptyViews(cache::roomMessages());
emit initializeRoomList(cache::roomInfo());
emit initializeMentions(cache::getTimelineMentions());
diff --git a/src/ChatPage.h b/src/ChatPage.h
index bf649cc9..a29cea7b 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -130,7 +130,7 @@ signals:
void contentLoaded();
void closing();
- void changeWindowTitle(const QString &msg);
+ void changeWindowTitle(const int);
void unreadMessages(int count);
void showNotification(const QString &msg);
void showLoginPage(const QString &msg);
@@ -188,7 +188,6 @@ signals:
void receivedDeviceVerificationDone(const mtx::events::msg::KeyVerificationDone &message);
private slots:
- void showUnreadMessageNotification(int count);
void logout();
void removeRoom(const QString &room_id);
void dropToLoginPage(const QString &msg);
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index b6ad8bbe..c019b24b 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -53,10 +53,11 @@
MainWindow *MainWindow::instance_ = nullptr;
-MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
+MainWindow::MainWindow(const QString profile, QWidget *parent)
+ : QMainWindow(parent),
+ profile_{ profile }
{
- setWindowTitle("nheko");
+ setWindowTitle(0);
setObjectName("MainWindow");
modal_ = new OverlayModal(this);
@@ -104,7 +105,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(
chat_page_, &ChatPage::showOverlayProgressBar, this, &MainWindow::showOverlayProgressBar);
connect(
- chat_page_, SIGNAL(changeWindowTitle(QString)), this, SLOT(setWindowTitle(QString)));
+ chat_page_, &ChatPage::unreadMessages, this, &MainWindow::setWindowTitle);
connect(chat_page_, SIGNAL(unreadMessages(int)), trayIcon_, SLOT(setUnreadCount(int)));
connect(chat_page_, &ChatPage::showLoginPage, this, [this](const QString &msg) {
login_page_->loginError(msg);
@@ -179,6 +180,19 @@ MainWindow::MainWindow(QWidget *parent)
}
void
+MainWindow::setWindowTitle(int notificationCount)
+{
+ QString name = "nheko";
+ if (!profile_.isEmpty())
+ name += " | " + profile_;
+ if (notificationCount > 0)
+ {
+ name.append(QString{" (%1)"}.arg(notificationCount));
+ }
+ QMainWindow::setWindowTitle(name);
+}
+
+void
MainWindow::showEvent(QShowEvent *event)
{
adjustSideBars();
diff --git a/src/MainWindow.h b/src/MainWindow.h
index e66f299f..2f9ff897 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -62,7 +62,7 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
- explicit MainWindow(QWidget *parent = nullptr);
+ explicit MainWindow(const QString name, QWidget *parent = nullptr);
static MainWindow *instance() { return instance_; };
void saveCurrentWindowSize();
@@ -113,6 +113,8 @@ private slots:
void showOverlayProgressBar();
void removeOverlayProgressBar();
+ virtual void setWindowTitle(int notificationCount);
+
private:
bool loadJdenticonPlugin();
@@ -147,4 +149,6 @@ private:
LoadingIndicator *spinner_ = nullptr;
JdenticonInterface *jdenticonInteface_ = nullptr;
+
+ QString profile_;
};
diff --git a/src/Olm.cpp b/src/Olm.cpp
index d6e8c10b..6e68bd42 100644
--- a/src/Olm.cpp
+++ b/src/Olm.cpp
@@ -369,6 +369,8 @@ create_inbound_megolm_session(const mtx::events::DeviceEvent<mtx::events::msg::R
nhlog::crypto()->info(
"established inbound megolm session ({}, {})", roomKey.content.room_id, roomKey.sender);
+
+ ChatPage::instance()->receivedSessionKey(index.room_id, index.session_id);
}
void
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index 4278180b..53539407 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -36,6 +36,7 @@
#include <QString>
#include <QTextStream>
#include <QtQml>
+#include <QCoreApplication>
#include "Cache.h"
#include "Config.h"
@@ -75,6 +76,7 @@ UserSettings::load()
decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool();
shareKeysWithTrustedUsers_ =
settings.value("user/share_keys_with_trusted_users", true).toBool();
+ mobileMode_ = settings.value("user/mobile_mode", false).toBool();
emojiFont_ = settings.value("user/emoji_font_family", "default").toString();
baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble();
presence_ =
@@ -124,6 +126,16 @@ UserSettings::setStartInTray(bool state)
}
void
+UserSettings::setMobileMode(bool state)
+{
+ if (state == mobileMode_)
+ return;
+ mobileMode_ = state;
+ emit mobileModeChanged(state);
+ save();
+}
+
+void
UserSettings::setGroupView(bool state)
{
if (groupView_ != state)
@@ -299,6 +311,7 @@ UserSettings::setShareKeysWithTrustedUsers(bool shareKeys)
{
if (shareKeys == shareKeysWithTrustedUsers_)
return;
+
shareKeysWithTrustedUsers_ = shareKeys;
emit shareKeysWithTrustedUsersChanged(shareKeys);
save();
@@ -388,6 +401,7 @@ UserSettings::save()
settings.setValue("avatar_circles", avatarCircles_);
settings.setValue("decrypt_sidebar", decryptSidebar_);
settings.setValue("share_keys_with_trusted_users", shareKeysWithTrustedUsers_);
+ settings.setValue("mobile_mode", mobileMode_);
settings.setValue("font_size", baseFontSize_);
settings.setValue("typing_notifications", typingNotifications_);
settings.setValue("minor_events", sortByImportance_);
@@ -433,6 +447,8 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
font.setPointSizeF(font.pointSizeF() * 1.1);
auto versionInfo = new QLabel(QString("%1 | %2").arg(nheko::version).arg(nheko::build_os));
+ if (QCoreApplication::applicationName() != "nheko")
+ versionInfo->setText(versionInfo->text() + " | " + tr("profile: %1").arg(QCoreApplication::applicationName()));
versionInfo->setTextInteractionFlags(Qt::TextBrowserInteraction);
topBarLayout_ = new QHBoxLayout;
@@ -469,6 +485,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
desktopNotifications_ = new Toggle{this};
alertOnNotification_ = new Toggle{this};
useStunServer_ = new Toggle{this};
+ mobileMode_ = new Toggle{this};
scaleFactorCombo_ = new QComboBox{this};
fontSizeCombo_ = new QComboBox{this};
fontSelectionCombo_ = new QFontComboBox{this};
@@ -636,6 +653,9 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
formLayout_->addRow(uiLabel_);
formLayout_->addRow(new HorizontalLine{this});
+ boxWrap(tr("Mobile mode"),
+ mobileMode_,
+ tr("Will prevent text selection in the timeline to make scrolling easier."));
#if !defined(Q_OS_MAC)
boxWrap(tr("Scale factor"),
scaleFactorCombo_,
@@ -727,6 +747,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
settings_->setStartInTray(!disabled);
});
+ connect(mobileMode_, &Toggle::toggled, this, [this](bool disabled) {
+ settings_->setMobileMode(!disabled);
+ });
+
connect(groupViewToggle_, &Toggle::toggled, this, [this](bool disabled) {
settings_->setGroupView(!disabled);
});
@@ -736,6 +760,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
emit decryptSidebarChanged();
});
+ connect(shareKeysWithTrustedUsers_, &Toggle::toggled, this, [this](bool disabled) {
+ settings_->setShareKeysWithTrustedUsers(!disabled);
+ });
+
connect(avatarCircles_, &Toggle::toggled, this, [this](bool disabled) {
settings_->setAvatarCircles(!disabled);
});
@@ -810,10 +838,12 @@ UserSettingsPage::showEvent(QShowEvent *)
startInTrayToggle_->setState(!settings_->startInTray());
groupViewToggle_->setState(!settings_->groupView());
decryptSidebar_->setState(!settings_->decryptSidebar());
+ shareKeysWithTrustedUsers_->setState(!settings_->shareKeysWithTrustedUsers());
avatarCircles_->setState(!settings_->avatarCircles());
typingNotifications_->setState(!settings_->typingNotifications());
sortByImportance_->setState(!settings_->sortByImportance());
timelineButtonsToggle_->setState(!settings_->buttonsInTimeline());
+ mobileMode_->setState(!settings_->mobileMode());
readReceipts_->setState(!settings_->readReceipts());
markdown_->setState(!settings_->markdown());
desktopNotifications_->setState(!settings_->hasDesktopNotifications());
diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index 37355602..ffe98542 100644
--- a/src/UserSettingsPage.h
+++ b/src/UserSettingsPage.h
@@ -67,6 +67,7 @@ class UserSettings : public QObject
decryptSidebarChanged)
Q_PROPERTY(int timelineMaxWidth READ timelineMaxWidth WRITE setTimelineMaxWidth NOTIFY
timelineMaxWidthChanged)
+ Q_PROPERTY(bool mobileMode READ mobileMode WRITE setMobileMode NOTIFY mobileModeChanged)
Q_PROPERTY(double fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
Q_PROPERTY(QString font READ font WRITE setFontFamily NOTIFY fontChanged)
Q_PROPERTY(
@@ -99,6 +100,7 @@ public:
void setEnlargeEmojiOnlyMessages(bool state);
void setTray(bool state);
void setStartInTray(bool state);
+ void setMobileMode(bool mode);
void setFontSize(double size);
void setFontFamily(QString family);
void setEmojiFontFamily(QString family);
@@ -130,6 +132,7 @@ public:
bool typingNotifications() const { return typingNotifications_; }
bool sortByImportance() const { return sortByImportance_; }
bool buttonsInTimeline() const { return buttonsInTimeline_; }
+ bool mobileMode() const { return mobileMode_; }
bool readReceipts() const { return readReceipts_; }
bool hasDesktopNotifications() const { return hasDesktopNotifications_; }
bool hasAlertOnNotification() const { return hasAlertOnNotification_; }
@@ -163,6 +166,7 @@ signals:
void avatarCirclesChanged(bool state);
void decryptSidebarChanged(bool state);
void timelineMaxWidthChanged(int state);
+ void mobileModeChanged(bool mode);
void fontSizeChanged(double state);
void fontChanged(QString state);
void emojiFontChanged(QString state);
@@ -193,6 +197,7 @@ private:
bool avatarCircles_;
bool decryptSidebar_;
bool shareKeysWithTrustedUsers_;
+ bool mobileMode_;
int timelineMaxWidth_;
double baseFontSize_;
QString font_;
@@ -256,6 +261,7 @@ private:
Toggle *useStunServer_;
Toggle *decryptSidebar_;
Toggle *shareKeysWithTrustedUsers_;
+ Toggle *mobileMode_;
QLabel *deviceFingerprintValue_;
QLabel *deviceIdValue_;
diff --git a/src/main.cpp b/src/main.cpp
index e02ffa36..61cb4fbe 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -104,10 +104,37 @@ createCacheDirectory()
int
main(int argc, char *argv[])
{
- // needed for settings so need to register before any settings are read to prevent warings
+ // needed for settings so need to register before any settings are read to prevent warnings
qRegisterMetaType<UserSettings::Presence>();
- QCoreApplication::setApplicationName("nheko");
+ // This is some hacky programming, but it's necessary (AFAIK?) to get the unique config name parsed
+ // before the app name is set.
+ QString appName{"nheko"};
+ for (int i = 0; i < argc; ++i)
+ {
+ if (QString{argv[i]}.startsWith("--profile="))
+ {
+ QString q{argv[i]};
+ q.remove("--profile=");
+ appName += "-" + q;
+ }
+ else if (QString{argv[i]}.startsWith("--p="))
+ {
+ QString q{argv[i]};
+ q.remove("-p=");
+ appName += "-" + q;
+ }
+ else if (QString{argv[i]} == "--profile" || QString{argv[i]} == "-p")
+ {
+ if (i < argc -1) // if i is less than argc - 1, we still have a parameter left to process as the name
+ {
+ ++i; // the next arg is the name, so increment
+ appName += "-" + QString {argv[i]};
+ }
+ }
+ }
+
+ QCoreApplication::setApplicationName(appName);
QCoreApplication::setApplicationVersion(nheko::version);
QCoreApplication::setOrganizationName("nheko");
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
@@ -137,6 +164,15 @@ main(int argc, char *argv[])
parser.addVersionOption();
QCommandLineOption debugOption("debug", "Enable debug output");
parser.addOption(debugOption);
+
+ // This option is not actually parsed via Qt due to the need to parse it before the app
+ // name is set. It only exists to keep Qt from complaining about the --profile/-p
+ // option and thereby crashing the app.
+ QCommandLineOption configName(QStringList() << "p" << "profile",
+ QCoreApplication::tr("Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko."),
+ QCoreApplication::tr("profile"), QCoreApplication::tr("profile name"));
+ parser.addOption(configName);
+
parser.process(app);
app.setWindowIcon(QIcon(":/logos/nheko.png"));
@@ -181,7 +217,7 @@ main(int argc, char *argv[])
appTranslator.load(QLocale(), "nheko", "_", ":/translations");
app.installTranslator(&appTranslator);
- MainWindow w;
+ MainWindow w{ (appName == "nheko" ? "" : appName.remove("nheko-")) };
// Move the MainWindow to the center
w.move(screenCenter(w.width(), w.height()));
diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index 22809a20..38292f49 100644
--- a/src/timeline/EventStore.cpp
+++ b/src/timeline/EventStore.cpp
@@ -54,8 +54,11 @@ EventStore::EventStore(std::string room_id, QObject *)
&EventStore::oldMessagesRetrieved,
this,
[this](const mtx::responses::Messages &res) {
- if (cache::client()->previousBatchToken(room_id_) == res.end)
+ if (cache::client()->previousBatchToken(room_id_) == res.end) {
noMoreMessages = true;
+ emit fetchedMore();
+ return;
+ }
uint64_t newFirst = cache::client()->saveOldMessages(room_id_, res);
if (newFirst == first)
|