diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml
index ed065270..465a8e1c 100644
--- a/resources/qml/Avatar.qml
+++ b/resources/qml/Avatar.qml
@@ -6,7 +6,7 @@ Rectangle {
id: avatar
width: 48
height: 48
- radius: settings.avatar_circles ? height/2 : 3
+ radius: settings.avatarCircles ? height/2 : 3
property alias url: img.source
property string displayName
@@ -39,7 +39,7 @@ Rectangle {
anchors.fill: parent
width: avatar.width
height: avatar.height
- radius: settings.avatar_circles ? height/2 : 3
+ radius: settings.avatarCircles ? height/2 : 3
}
}
}
diff --git a/resources/qml/Reactions.qml b/resources/qml/Reactions.qml
index cb15b723..f42e8612 100644
--- a/resources/qml/Reactions.qml
+++ b/resources/qml/Reactions.qml
@@ -30,7 +30,7 @@ Flow {
TextMetrics {
id: textMetrics
- font.family: settings.emoji_font_family
+ font.family: settings.emojiFont
elide: Text.ElideRight
elideWidth: 150
text: reaction.text
@@ -40,14 +40,14 @@ Flow {
anchors.baseline: reactionCounter.baseline
id: reactionText
text: textMetrics.elidedText + (textMetrics.elidedText == textMetrics.text ? "" : "…")
- font.family: settings.emoji_font_family
+ font.family: settings.emojiFont
color: reaction.hovered ? colors.highlight : colors.text
maximumLineCount: 1
}
Rectangle {
id: divider
- height: reactionCounter.implicitHeight * 1.4
+ height: Math.floor(reactionCounter.implicitHeight * 1.4)
width: 1
color: reaction.hovered ? colors.highlight : colors.text
}
@@ -64,7 +64,7 @@ Flow {
background: Rectangle {
anchors.centerIn: parent
implicitWidth: reaction.implicitWidth
- implicitHeight: reaction.implicitHeight
+ height: reaction.implicitHeight
border.color: (reaction.hovered || model.selfReacted )? colors.highlight : colors.text
color: colors.base
border.width: 1
diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml
index 42791e0b..c8e6eb09 100644
--- a/resources/qml/TimelineRow.qml
+++ b/resources/qml/TimelineRow.qml
@@ -25,13 +25,13 @@ MouseArea {
messageContextMenu.show(model.id, model.type, model.isEncrypted, row)
}
Rectangle {
- color: (timelineSettings.message_hover_highlight && parent.containsMouse) ? colors.base : "transparent"
+ color: (settings.isMessageHoverHighlightEnabled && parent.containsMouse) ? colors.base : "transparent"
anchors.fill: row
}
RowLayout {
id: row
- anchors.leftMargin: avatarSize + 4
+ anchors.leftMargin: avatarSize + 16
anchors.left: parent.left
anchors.right: parent.right
@@ -78,7 +78,7 @@ MouseArea {
}
ImageButton {
- visible: timelineSettings.buttons
+ visible: settings.buttonsInTimeline
Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 16
width: 16
@@ -94,7 +94,7 @@ MouseArea {
onClicked: chat.model.replyAction(model.id)
}
ImageButton {
- visible: timelineSettings.buttons
+ visible: settings.buttonsInTimeline
Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 16
width: 16
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 145a82ce..08130033 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -3,7 +3,6 @@ import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2
import QtGraphicalEffects 1.0
import QtQuick.Window 2.2
-import Qt.labs.settings 1.0
import im.nheko 1.0
@@ -21,22 +20,6 @@ Page {
id: fontMetrics
}
- Settings {
- id: settings
- category: "user"
- property bool avatar_circles: true
- property string emoji_font_family: "default"
- property double font_size: Qt.application.font.pointSize
- }
-
- Settings {
- id: timelineSettings
- category: "user/timeline"
- property bool buttons: true
- property bool message_hover_highlight: false
- property bool enlarge_emoji_only_msg: false
- }
-
Menu {
id: messageContextMenu
modal: true
@@ -102,7 +85,7 @@ Page {
BusyIndicator {
visible: running
anchors.centerIn: parent
- running: timelineManager.isInitialSync
+ running: timelineManager.isInitialSync
height: 200
width: 200
z: 3
@@ -113,12 +96,12 @@ Page {
visible: timelineManager.timeline != null
- cacheBuffer: 500
+ cacheBuffer: 400
- anchors.left: parent.left
- anchors.right: parent.right
+ anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.bottom: chatFooter.top
+ width: parent.width
anchors.leftMargin: 4
anchors.rightMargin: scrollbar.width
@@ -160,7 +143,7 @@ Page {
id: scrollbar
parent: chat.parent
anchors.top: chat.top
- anchors.left: chat.right
+ anchors.right: chat.right
anchors.bottom: chat.bottom
}
@@ -175,7 +158,8 @@ Page {
id: wrapper
property Item section
- width: chat.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: (settings.timelineMaxWidth > 100 && (parent.width - settings.timelineMaxWidth) > 32) ? settings.timelineMaxWidth : (parent.width - 32)
height: section ? section.height + timelinerow.height : timelinerow.height
color: "transparent"
@@ -245,7 +229,8 @@ Page {
}
Row {
height: userName.height
- spacing: 4
+ spacing: 8
+
Avatar {
width: avatarSize
height: avatarSize
diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml
index d17723f3..b3c45c36 100644
--- a/resources/qml/delegates/TextMessage.qml
+++ b/resources/qml/delegates/TextMessage.qml
@@ -6,5 +6,5 @@ MatrixText {
width: parent ? parent.width : undefined
height: isReply ? Math.min(chat.height / 8, implicitHeight) : undefined
clip: true
- font.pointSize: (timelineSettings.enlarge_emoji_only_msg && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? settings.font_size * 3 : settings.font_size
+ font.pointSize: (settings.enlargeEmojiOnlyMessages && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? settings.fontSize * 3 : settings.fontSize
}
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index c151cad2..393b4861 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -30,6 +30,7 @@
#include <QScrollArea>
#include <QScroller>
#include <QSettings>
+#include <QSpinBox>
#include <QStandardPaths>
#include <QString>
#include <QTextStream>
@@ -56,6 +57,7 @@ UserSettings::load()
isStartInTrayEnabled_ = settings.value("user/window/start_in_tray", false).toBool();
isGroupViewEnabled_ = settings.value("user/group_view", true).toBool();
isButtonsInTimelineEnabled_ = settings.value("user/timeline/buttons", true).toBool();
+ timelineMaxWidth_ = settings.value("user/timeline/max_width", 0).toInt();
isMessageHoverHighlightEnabled_ =
settings.value("user/timeline/message_hover_highlight", false).toBool();
isEnlargeEmojiOnlyMessagesEnabled_ =
@@ -73,34 +75,183 @@ UserSettings::load()
applyTheme();
}
+void
+UserSettings::setMessageHoverHighlight(bool state)
+{
+ if (state == isMessageHoverHighlightEnabled_)
+ return;
+ isMessageHoverHighlightEnabled_ = state;
+ emit messageHoverHighlightChanged(state);
+ save();
+}
+void
+UserSettings::setEnlargeEmojiOnlyMessages(bool state)
+{
+ if (state == isEnlargeEmojiOnlyMessagesEnabled_)
+ return;
+ isEnlargeEmojiOnlyMessagesEnabled_ = state;
+ emit enlargeEmojiOnlyMessagesChanged(state);
+ save();
+}
+void
+UserSettings::setTray(bool state)
+{
+ if (state == isTrayEnabled_)
+ return;
+ isTrayEnabled_ = state;
+ emit trayChanged(state);
+ save();
+}
+
+void
+UserSettings::setStartInTray(bool state)
+{
+ if (state == isStartInTrayEnabled_)
+ return;
+ isStartInTrayEnabled_ = state;
+ emit startInTrayChanged(state);
+ save();
+}
+
+void
+UserSettings::setGroupView(bool state)
+{
+ if (isGroupViewEnabled_ != state)
+ emit groupViewStateChanged(state);
+
+ isGroupViewEnabled_ = state;
+ save();
+}
+
+void
+UserSettings::setMarkdownEnabled(bool state)
+{
+ if (state == isMarkdownEnabled_)
+ return;
+ isMarkdownEnabled_ = state;
+ emit markdownChanged(state);
+ save();
+}
+
+void
+UserSettings::setReadReceipts(bool state)
+{
+ if (state == isReadReceiptsEnabled_)
+ return;
+ isReadReceiptsEnabled_ = state;
+ emit readReceiptsChanged(state);
+ save();
+}
+
+void
+UserSettings::setTypingNotifications(bool state)
+{
+ if (state == isTypingNotificationsEnabled_)
+ return;
+ isTypingNotificationsEnabled_ = state;
+ emit typingNotificationsChanged(state);
+ save();
+}
+
+void
+UserSettings::setSortByImportance(bool state)
+{
+ if (state == sortByImportance_)
+ return;
+ sortByImportance_ = state;
+ emit roomSortingChanged(state);
+ save();
+}
+
+void
+UserSettings::setButtonsInTimeline(bool state)
+{
+ if (state == isButtonsInTimelineEnabled_)
+ return;
+ isButtonsInTimelineEnabled_ = state;
+ emit buttonInTimelineChanged(state);
+ save();
+}
+
+void
+UserSettings::setTimelineMaxWidth(int state)
+{
+ if (state == timelineMaxWidth_)
+ return;
+ timelineMaxWidth_ = state;
+ emit timelineMaxWidthChanged(state);
+ save();
+}
+
+void
+UserSettings::setDesktopNotifications(bool state)
+{
+ if (state == hasDesktopNotifications_)
+ return;
+ hasDesktopNotifications_ = state;
+ emit desktopNotificationsChanged(state);
+ save();
+}
+
+void
+UserSettings::setAvatarCircles(bool state)
+{
+ if (state == avatarCircles_)
+ return;
+ avatarCircles_ = state;
+ emit avatarCirclesChanged(state);
+ save();
+}
+
+void
+UserSettings::setDecryptSidebar(bool state)
+{
+ if (state == decryptSidebar_)
+ return;
+ decryptSidebar_ = state;
+ emit decryptSidebarChanged(state);
+ save();
+}
void
UserSettings::setFontSize(double size)
{
+ if (size == baseFontSize_)
+ return;
baseFontSize_ = size;
+ emit fontSizeChanged(size);
save();
}
void
UserSettings::setFontFamily(QString family)
{
+ if (family == font_)
+ return;
font_ = family;
+ emit fontChanged(family);
save();
}
void
UserSettings::setEmojiFontFamily(QString family)
{
+ if (family == emojiFont_)
+ return;
emojiFont_ = family;
+ emit emojiFontChanged(family);
save();
}
void
UserSettings::setTheme(QString theme)
{
+ if (theme == theme)
+ return;
theme_ = theme;
save();
applyTheme();
+ emit themeChanged(theme);
}
void
@@ -171,6 +322,7 @@ UserSettings::save()
settings.setValue("buttons", isButtonsInTimelineEnabled_);
settings.setValue("message_hover_highlight", isMessageHoverHighlightEnabled_);
settings.setValue("enlarge_emoji_only_msg", isEnlargeEmojiOnlyMessagesEnabled_);
+ settings.setValue("max_width", timelineMaxWidth_);
settings.endGroup();
settings.setValue("avatar_circles", avatarCircles_);
@@ -187,6 +339,8 @@ UserSettings::save()
settings.setValue("emoji_font_family", emojiFont_);
settings.endGroup();
+
+ settings.sync();
}
HorizontalLine::HorizontalLine(QWidget *parent)
@@ -251,6 +405,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
fontSizeCombo_ = new QComboBox{this};
fontSelectionCombo_ = new QComboBox{this};
emojiFontSelectionCombo_ = new QComboBox{this};
+ timelineMaxWidthSpin_ = new QSpinBox{this};
if (!settings_->isTrayEnabled())
startInTrayToggle_->setDisabled(true);
@@ -295,6 +450,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
int themeIndex = themeCombo_->findText(themeStr);
themeCombo_->setCurrentIndex(themeIndex);
+ timelineMaxWidthSpin_->setMinimum(0);
+ timelineMaxWidthSpin_->setMaximum(100'000'000);
+ timelineMaxWidthSpin_->setSingleStep(10);
+
auto encryptionLabel_ = new QLabel{tr("ENCRYPTION"), this};
encryptionLabel_->setFixedHeight(encryptionLabel_->minimumHeight() + LayoutTopMargin);
encryptionLabel_->setAlignment(Qt::AlignBottom);
@@ -366,6 +525,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
timelineButtonsToggle_,
tr("Show buttons to quickly reply, react or access additional options next to each "
"message."));
+ boxWrap(tr("Limit width of timeline"),
+ timelineMaxWidthSpin_,
+ tr("Set the max width of messages in the timeline (in pixels). This can help "
+ "readability on wide screen, when Nheko is maximised"));
boxWrap(tr("Typing notifications"),
typingNotifications_,
tr("Show who is typing in a room.\nThis will also enable or disable sending typing "
@@ -525,6 +688,11 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
settings_->setEnlargeEmojiOnlyMessages(!isDisabled);
});
+ connect(timelineMaxWidthSpin_,
+ qOverload<int>(&QSpinBox::valueChanged),
+ this,
+ [this](int newValue) { settings_->setTimelineMaxWidth(newValue); });
+
connect(
sessionKeysImportBtn, &QPushButton::clicked, this, &UserSettingsPage::importSessionKeys);
@@ -560,6 +728,7 @@ UserSettingsPage::showEvent(QShowEvent *)
messageHoverHighlight_->setState(!settings_->isMessageHoverHighlightEnabled());
enlargeEmojiOnlyMessages_->setState(!settings_->isEnlargeEmojiOnlyMessagesEnabled());
deviceIdValue_->setText(QString::fromStdString(http::client()->device_id()));
+ timelineMaxWidthSpin_->setValue(settings_->timelineMaxWidth());
deviceFingerprintValue_->setText(
utils::humanReadableFingerprint(olm::client()->identity_keys().ed25519));
diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index f80c2b2b..cade8c22 100644
--- a/src/UserSettingsPage.h
+++ b/src/UserSettingsPage.h
@@ -27,6 +27,7 @@ class Toggle;
class QLabel;
class QFormLayout;
class QComboBox;
+class QSpinBox;
class QHBoxLayout;
class QVBoxLayout;
@@ -38,6 +39,39 @@ class UserSettings : public QObject
{
Q_OBJECT
+ Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged)
+ Q_PROPERTY(bool isMessageHoverHighlightEnabled READ isMessageHoverHighlightEnabled WRITE
+ setMessageHoverHighlight NOTIFY messageHoverHighlightChanged)
+ Q_PROPERTY(bool enlargeEmojiOnlyMessages READ isEnlargeEmojiOnlyMessagesEnabled WRITE
+ setEnlargeEmojiOnlyMessages NOTIFY enlargeEmojiOnlyMessagesChanged)
+ Q_PROPERTY(bool trayEnabled READ isTrayEnabled WRITE setTray NOTIFY trayChanged)
+ Q_PROPERTY(bool startInTrayEnabled READ isStartInTrayEnabled WRITE setStartInTray NOTIFY
+ startInTrayChanged)
+ Q_PROPERTY(bool groupViewEnabled READ isGroupViewEnabled WRITE setGroupView NOTIFY
+ groupViewStateChanged)
+ Q_PROPERTY(
+ bool markdown READ isMarkdownEnabled WRITE setMarkdownEnabled NOTIFY markdownChanged)
+ Q_PROPERTY(bool typingNotifications READ isTypingNotificationsEnabled WRITE
+ setTypingNotifications NOTIFY typingNotificationsChanged)
+ Q_PROPERTY(bool sortByImportance READ isSortByImportanceEnabled WRITE setSortByImportance
+ NOTIFY roomSortingChanged)
+ Q_PROPERTY(bool buttonsInTimeline READ isButtonsInTimelineEnabled WRITE setButtonsInTimeline
+ NOTIFY buttonInTimelineChanged)
+ Q_PROPERTY(bool readReceipts READ isReadReceiptsEnabled WRITE setReadReceipts NOTIFY
+ readReceiptsChanged)
+ Q_PROPERTY(bool desktopNotifications READ hasDesktopNotifications WRITE
+ setDesktopNotifications NOTIFY desktopNotificationsChanged)
+ Q_PROPERTY(bool avatarCircles READ isAvatarCirclesEnabled WRITE setAvatarCircles NOTIFY
+ avatarCirclesChanged)
+ Q_PROPERTY(bool decryptSidebar READ isDecryptSidebarEnabled WRITE setDecryptSidebar NOTIFY
+ decryptSidebarChanged)
+ Q_PROPERTY(int timelineMaxWidth READ timelineMaxWidth WRITE setTimelineMaxWidth NOTIFY
+ timelineMaxWidthChanged)
+ Q_PROPERTY(double fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
+ Q_PROPERTY(QString font READ font WRITE setFontFamily NOTIFY fontChanged)
+ Q_PROPERTY(
+ QString emojiFont READ emojiFont WRITE setEmojiFontFamily NOTIFY emojiFontChanged)
+
public:
UserSettings();
@@ -45,88 +79,23 @@ public:
void load();
void applyTheme();
void setTheme(QString theme);
- void setMessageHoverHighlight(bool state)
- {
- isMessageHoverHighlightEnabled_ = state;
- save();
- }
- void setEnlargeEmojiOnlyMessages(bool state)
- {
- isEnlargeEmojiOnlyMessagesEnabled_ = state;
- save();
- }
- void setTray(bool state)
- {
- isTrayEnabled_ = state;
- save();
- }
-
- void setStartInTray(bool state)
- {
- isStartInTrayEnabled_ = state;
- save();
- }
-
+ void setMessageHoverHighlight(bool state);
+ void setEnlargeEmojiOnlyMessages(bool state);
+ void setTray(bool state);
+ void setStartInTray(bool state);
void setFontSize(double size);
void setFontFamily(QString family);
void setEmojiFontFamily(QString family);
-
- void setGroupView(bool state)
- {
- if (isGroupViewEnabled_ != state)
- emit groupViewStateChanged(state);
-
- isGroupViewEnabled_ = state;
- save();
- }
-
- void setMarkdownEnabled(bool state)
- {
- isMarkdownEnabled_ = state;
- save();
- }
-
- void setReadReceipts(bool state)
- {
- isReadReceiptsEnabled_ = state;
- save();
- }
-
- void setTypingNotifications(bool state)
- {
- isTypingNotificationsEnabled_ = state;
- save();
- }
-
- void setSortByImportance(bool state)
- {
- sortByImportance_ = state;
- emit roomSortingChanged();
- }
-
- void setButtonsInTimeline(bool state)
- {
- isButtonsInTimelineEnabled_ = state;
- save();
- }
-
- void setDesktopNotifications(bool state)
- {
- hasDesktopNotifications_ = state;
- save();
- }
-
- void setAvatarCircles(bool state)
- {
- avatarCircles_ = state;
- save();
- }
-
- void setDecryptSidebar(bool state)
- {
- decryptSidebar_ = state;
- save();
- }
+ void setGroupView(bool state);
+ void setMarkdownEnabled(bool state);
+ void setReadReceipts(bool state);
+ void setTypingNotifications(bool state);
+ void setSortByImportance(bool state);
+ void setButtonsInTimeline(bool state);
+ void setTimelineMaxWidth(int state);
+ void setDesktopNotifications(bool state);
+ void setAvatarCircles(bool state);
+ void setDecryptSidebar(bool state);
QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; }
bool isMessageHoverHighlightEnabled() const { return isMessageHoverHighlightEnabled_; }
@@ -145,13 +114,30 @@ public:
bool isButtonsInTimelineEnabled() const { return isButtonsInTimelineEnabled_; }
bool isReadReceiptsEnabled() const { return isReadReceiptsEnabled_; }
bool hasDesktopNotifications() const { return hasDesktopNotifications_; }
+ int timelineMaxWidth() const { return timelineMaxWidth_; }
double fontSize() const { return baseFontSize_; }
QString font() const { return font_; }
QString emojiFont() const { return emojiFont_; }
signals:
void groupViewStateChanged(bool state);
- void roomSortingChanged();
+ void roomSortingChanged(bool state);
+ void themeChanged(QString state);
+ void messageHoverHighlightChanged(bool state);
+ void enlargeEmojiOnlyMessagesChanged(bool state);
+ void trayChanged(bool state);
+ void startInTrayChanged(bool state);
+ void markdownChanged(bool state);
+ void typingNotificationsChanged(bool state);
+ void buttonInTimelineChanged(bool state);
+ void readReceiptsChanged(bool state);
+ void desktopNotificationsChanged(bool state);
+ void avatarCirclesChanged(bool state);
+ void decryptSidebarChanged(bool state);
+ void timelineMaxWidthChanged(int state);
+ void fontSizeChanged(double state);
+ void fontChanged(QString state);
+ void emojiFontChanged(QString state);
private:
// Default to system theme if QT_QPA_PLATFORMTHEME var is set.
@@ -173,6 +159,7 @@ private:
bool hasDesktopNotifications_;
bool avatarCircles_;
bool decryptSidebar_;
+ int timelineMaxWidth_;
double baseFontSize_;
QString font_;
QString emojiFont_;
@@ -238,5 +225,7 @@ private:
QComboBox *fontSelectionCombo_;
QComboBox *emojiFontSelectionCombo_;
+ QSpinBox *timelineMaxWidthSpin_;
+
int sideMargin_ = 0;
};
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index b9565be8..89882e9d 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -88,6 +88,7 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
#endif
container->setMinimumSize(200, 200);
view->rootContext()->setContextProperty("timelineManager", this);
+ view->rootContext()->setContextProperty("settings", settings.data());
updateColorPalette();
view->engine()->addImageProvider("MxcImage", imgProvider);
view->engine()->addImageProvider("colorimage", colorImgProvider);
|