summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2020-05-26 22:27:05 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2020-05-26 22:54:51 +0200
commitf452bdf2b01ca6c39bdb3ecd4f61ec1eb1eef211 (patch)
tree42281470d39f726b69eeedfb1ff3055935414fe4
parentImprove compile times a tiny bit (diff)
downloadnheko-f452bdf2b01ca6c39bdb3ecd4f61ec1eb1eef211.tar.xz
Make settings update immediately in qml and allow limiting timeline width
Limiting improves readability on wide monitors.

The immediate update of the settings is done by just exposing settings
as properties and then setting the settings as a context property.
-rw-r--r--resources/qml/Avatar.qml4
-rw-r--r--resources/qml/Reactions.qml8
-rw-r--r--resources/qml/TimelineRow.qml8
-rw-r--r--resources/qml/TimelineView.qml33
-rw-r--r--resources/qml/delegates/TextMessage.qml2
-rw-r--r--src/UserSettingsPage.cpp169
-rw-r--r--src/UserSettingsPage.h149
-rw-r--r--src/timeline/TimelineViewManager.cpp1
8 files changed, 259 insertions, 115 deletions
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);