summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/ChatPage.cpp4
-rw-r--r--src/CommunitiesList.cpp11
-rw-r--r--src/CommunitiesList.h5
-rw-r--r--src/CommunitiesListItem.cpp3
-rw-r--r--src/CommunitiesListItem.h7
-rw-r--r--src/LoginPage.cpp1
-rw-r--r--src/MainWindow.cpp3
-rw-r--r--src/RegisterPage.cpp1
-rw-r--r--src/RoomInfoListItem.cpp6
-rw-r--r--src/RoomList.cpp6
-rw-r--r--src/SideBarActions.cpp8
-rw-r--r--src/SideBarActions.h2
-rw-r--r--src/Splitter.cpp22
-rw-r--r--src/Splitter.h16
-rw-r--r--src/TextInputWidget.cpp5
-rw-r--r--src/TextInputWidget.h1
-rw-r--r--src/TopRoomBar.cpp26
-rw-r--r--src/TopRoomBar.h35
-rw-r--r--src/TrayIcon.cpp2
-rw-r--r--src/TrayIcon.h5
-rw-r--r--src/UserInfoWidget.cpp5
-rw-r--r--src/UserSettingsPage.cpp1
-rw-r--r--src/Utils.cpp32
-rw-r--r--src/Utils.h33
-rw-r--r--src/WelcomePage.cpp1
-rw-r--r--src/dialogs/MemberList.cpp3
-rw-r--r--src/dialogs/UserProfile.cpp3
-rw-r--r--src/emoji/ItemDelegate.cpp1
-rw-r--r--src/emoji/Panel.cpp1
-rw-r--r--src/popups/UserMentions.h7
-rw-r--r--src/timeline/TimelineModel.h8
-rw-r--r--src/ui/DropShadow.cpp110
-rw-r--r--src/ui/DropShadow.h100
-rw-r--r--src/ui/FlatButton.cpp2
-rw-r--r--src/ui/FlatButton.h2
-rw-r--r--src/ui/FloatingButton.cpp1
-rw-r--r--src/ui/LoadingIndicator.cpp5
-rw-r--r--src/ui/LoadingIndicator.h6
-rw-r--r--src/ui/OverlayWidget.cpp4
-rw-r--r--src/ui/OverlayWidget.h4
41 files changed, 271 insertions, 228 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 96a6aec6..fe00d570 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -256,6 +256,7 @@ set(SRC_FILES
 	# UI components
 	src/ui/Avatar.cpp
 	src/ui/Badge.cpp
+	src/ui/DropShadow.cpp
 	src/ui/LoadingIndicator.cpp
 	src/ui/InfoMessage.cpp
 	src/ui/FlatButton.cpp
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 2191c6de..e54892a6 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -84,7 +84,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
         // SideBar
         sideBar_ = new QFrame(this);
         sideBar_->setObjectName("sideBar");
-        sideBar_->setMinimumWidth(utils::calculateSidebarSizes(QFont{}).normal);
+        sideBar_->setMinimumWidth(::splitter::calculateSidebarSizes(QFont{}).normal);
         sideBarLayout_ = new QVBoxLayout(sideBar_);
         sideBarLayout_->setSpacing(0);
         sideBarLayout_->setMargin(0);
@@ -1307,7 +1307,7 @@ ChatPage::timelineWidth()
 bool
 ChatPage::isSideBarExpanded()
 {
-        const auto sz = utils::calculateSidebarSizes(QFont{});
+        const auto sz = splitter::calculateSidebarSizes(QFont{});
         return sideBar_->size().width() > sz.normal;
 }
 
diff --git a/src/CommunitiesList.cpp b/src/CommunitiesList.cpp
index 4ea99408..2d97594a 100644
--- a/src/CommunitiesList.cpp
+++ b/src/CommunitiesList.cpp
@@ -2,7 +2,9 @@
 #include "Cache.h"
 #include "Logging.h"
 #include "MatrixClient.h"
-#include "Utils.h"
+#include "Splitter.h"
+
+#include <mtx/responses/groups.hpp>
 
 #include <QLabel>
 
@@ -20,7 +22,7 @@ CommunitiesList::CommunitiesList(QWidget *parent)
         topLayout_->setSpacing(0);
         topLayout_->setMargin(0);
 
-        const auto sideBarSizes = utils::calculateSidebarSizes(QFont{});
+        const auto sideBarSizes = splitter::calculateSidebarSizes(QFont{});
         setFixedWidth(sideBarSizes.groups);
 
         scrollArea_ = new QScrollArea(this);
@@ -185,7 +187,8 @@ void
 CommunitiesList::updateCommunityAvatar(const QString &community_id, const QPixmap &img)
 {
         if (!communityExists(community_id)) {
-                qWarning() << "Avatar update on nonexistent community" << community_id;
+                nhlog::ui()->warn("Avatar update on nonexistent community {}",
+                                  community_id.toStdString());
                 return;
         }
 
@@ -196,7 +199,7 @@ void
 CommunitiesList::highlightSelectedCommunity(const QString &community_id)
 {
         if (!communityExists(community_id)) {
-                qDebug() << "CommunitiesList: clicked unknown community";
+                nhlog::ui()->debug("CommunitiesList: clicked unknown community");
                 return;
         }
 
diff --git a/src/CommunitiesList.h b/src/CommunitiesList.h
index 49eaeaf6..e8042666 100644
--- a/src/CommunitiesList.h
+++ b/src/CommunitiesList.h
@@ -8,6 +8,11 @@
 #include "CommunitiesListItem.h"
 #include "ui/Theme.h"
 
+namespace mtx::responses {
+struct GroupProfile;
+struct JoinedGroups;
+}
+
 class CommunitiesList : public QWidget
 {
         Q_OBJECT
diff --git a/src/CommunitiesListItem.cpp b/src/CommunitiesListItem.cpp
index 324482d3..274271e5 100644
--- a/src/CommunitiesListItem.cpp
+++ b/src/CommunitiesListItem.cpp
@@ -1,4 +1,7 @@
 #include "CommunitiesListItem.h"
+
+#include <QMouseEvent>
+
 #include "Utils.h"
 #include "ui/Painter.h"
 #include "ui/Ripple.h"
diff --git a/src/CommunitiesListItem.h b/src/CommunitiesListItem.h
index d4d7e9c6..0cc5d60c 100644
--- a/src/CommunitiesListItem.h
+++ b/src/CommunitiesListItem.h
@@ -1,17 +1,14 @@
 #pragma once
 
-#include <QDebug>
-#include <QMouseEvent>
-#include <QPainter>
 #include <QSharedPointer>
 #include <QWidget>
 
-#include <mtx/responses/groups.hpp>
-
 #include "Config.h"
 #include "ui/Theme.h"
 
 class RippleOverlay;
+class QPainter;
+class QMouseEvent;
 
 class CommunitiesListItem : public QWidget
 {
diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp
index 0e7a18d4..c244db28 100644
--- a/src/LoginPage.cpp
+++ b/src/LoginPage.cpp
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QPainter>
 #include <QStyleOption>
 
 #include <mtx/identifiers.hpp>
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index a24266fa..d400ad8e 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -31,6 +31,7 @@
 #include "MainWindow.h"
 #include "MatrixClient.h"
 #include "RegisterPage.h"
+#include "Splitter.h"
 #include "TrayIcon.h"
 #include "UserSettingsPage.h"
 #include "Utils.h"
@@ -191,7 +192,7 @@ MainWindow::resizeEvent(QResizeEvent *event)
 void
 MainWindow::adjustSideBars()
 {
-        const auto sz = utils::calculateSidebarSizes(QFont{});
+        const auto sz = splitter::calculateSidebarSizes(QFont{});
 
         const uint64_t timelineWidth     = chat_page_->timelineWidth();
         const uint64_t minAvailableWidth = sz.collapsePoint + sz.groups;
diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp
index fdb0f43a..942fd1b8 100644
--- a/src/RegisterPage.cpp
+++ b/src/RegisterPage.cpp
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QPainter>
 #include <QStyleOption>
 #include <QTimer>
 
diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp
index 926e1359..822a7a55 100644
--- a/src/RoomInfoListItem.cpp
+++ b/src/RoomInfoListItem.cpp
@@ -16,7 +16,6 @@
  */
 
 #include <QDateTime>
-#include <QDebug>
 #include <QMouseEvent>
 #include <QPainter>
 #include <QSettings>
@@ -26,6 +25,7 @@
 #include "Cache.h"
 #include "Config.h"
 #include "RoomInfoListItem.h"
+#include "Splitter.h"
 #include "Utils.h"
 #include "ui/Menu.h"
 #include "ui/Ripple.h"
@@ -116,7 +116,7 @@ RoomInfoListItem::resizeEvent(QResizeEvent *)
         QPainterPath path;
         path.addRect(0, 0, width(), height());
 
-        const auto sidebarSizes = utils::calculateSidebarSizes(QFont{});
+        const auto sidebarSizes = splitter::calculateSidebarSizes(QFont{});
 
         if (width() > sidebarSizes.small)
                 setToolTip("");
@@ -165,7 +165,7 @@ RoomInfoListItem::paintEvent(QPaintEvent *event)
         // Description line with the default font.
         int bottom_y = wm.maxHeight - wm.padding - metrics.ascent() / 2;
 
-        const auto sidebarSizes = utils::calculateSidebarSizes(QFont{});
+        const auto sidebarSizes = splitter::calculateSidebarSizes(QFont{});
 
         if (width() > sidebarSizes.small) {
                 QFont headingFont;
diff --git a/src/RoomList.cpp b/src/RoomList.cpp
index 6434489e..b90c8fa4 100644
--- a/src/RoomList.cpp
+++ b/src/RoomList.cpp
@@ -17,18 +17,14 @@
 
 #include <limits>
 
-#include <QApplication>
-#include <QBuffer>
 #include <QObject>
+#include <QPainter>
 #include <QTimer>
 
-#include "Cache.h"
 #include "Logging.h"
 #include "MainWindow.h"
-#include "MatrixClient.h"
 #include "RoomInfoListItem.h"
 #include "RoomList.h"
-#include "UserSettingsPage.h"
 #include "Utils.h"
 #include "ui/OverlayModal.h"
 
diff --git a/src/SideBarActions.cpp b/src/SideBarActions.cpp
index 2f447cd8..4934ec05 100644
--- a/src/SideBarActions.cpp
+++ b/src/SideBarActions.cpp
@@ -1,15 +1,15 @@
-#include <QDebug>
 #include <QIcon>
+#include <QPainter>
+#include <QResizeEvent>
 
 #include <mtx/requests.hpp>
 
 #include "Config.h"
 #include "MainWindow.h"
 #include "SideBarActions.h"
-#include "Utils.h"
+#include "Splitter.h"
 #include "ui/FlatButton.h"
 #include "ui/Menu.h"
-#include "ui/OverlayModal.h"
 
 SideBarActions::SideBarActions(QWidget *parent)
   : QWidget{parent}
@@ -93,7 +93,7 @@ SideBarActions::resizeEvent(QResizeEvent *event)
 {
         Q_UNUSED(event);
 
-        const auto sidebarSizes = utils::calculateSidebarSizes(QFont{});
+        const auto sidebarSizes = splitter::calculateSidebarSizes(QFont{});
 
         if (width() <= sidebarSizes.small) {
                 roomDirectory_->hide();
diff --git a/src/SideBarActions.h b/src/SideBarActions.h
index ce96cba8..662750b3 100644
--- a/src/SideBarActions.h
+++ b/src/SideBarActions.h
@@ -2,7 +2,6 @@
 
 #include <QAction>
 #include <QHBoxLayout>
-#include <QResizeEvent>
 #include <QWidget>
 
 namespace mtx {
@@ -13,6 +12,7 @@ struct CreateRoom;
 
 class Menu;
 class FlatButton;
+class QResizeEvent;
 
 class SideBarActions : public QWidget
 {
diff --git a/src/Splitter.cpp b/src/Splitter.cpp
index ddb1dc1c..32c67425 100644
--- a/src/Splitter.cpp
+++ b/src/Splitter.cpp
@@ -16,19 +16,20 @@
  */
 
 #include <QApplication>
-#include <QDebug>
 #include <QDesktopWidget>
 #include <QSettings>
 #include <QShortcut>
 
 #include "Config.h"
+#include "Logging.h"
 #include "Splitter.h"
+#include "Utils.h"
 
 constexpr auto MaxWidth = (1 << 24) - 1;
 
 Splitter::Splitter(QWidget *parent)
   : QSplitter(parent)
-  , sz_{utils::calculateSidebarSizes(QFont{})}
+  , sz_{splitter::calculateSidebarSizes(QFont{})}
 {
         connect(this, &QSplitter::splitterMoved, this, &Splitter::onSplitterMoved);
         setChildrenCollapsible(false);
@@ -80,7 +81,7 @@ Splitter::onSplitterMoved(int pos, int index)
         auto s = sizes();
 
         if (s.count() < 2) {
-                qWarning() << "Splitter needs at least two children";
+                nhlog::ui()->warn("Splitter needs at least two children");
                 return;
         }
 
@@ -165,3 +166,18 @@ Splitter::showFullRoomList()
         left->show();
         left->setMaximumWidth(MaxWidth);
 }
+
+splitter::SideBarSizes
+splitter::calculateSidebarSizes(const QFont &f)
+{
+        const auto height = static_cast<double>(QFontMetrics{f}.lineSpacing());
+
+        SideBarSizes sz;
+        sz.small         = std::ceil(3.5 * height + height / 4.0);
+        sz.normal        = std::ceil(16 * height);
+        sz.groups        = std::ceil(3 * height);
+        sz.collapsePoint = 2 * sz.normal;
+
+        return sz;
+}
+
diff --git a/src/Splitter.h b/src/Splitter.h
index 14d6773e..36c9f4fb 100644
--- a/src/Splitter.h
+++ b/src/Splitter.h
@@ -17,9 +17,21 @@
 
 #pragma once
 
-#include "Utils.h"
 #include <QSplitter>
 
+namespace splitter {
+struct SideBarSizes
+{
+        int small;
+        int normal;
+        int groups;
+        int collapsePoint;
+};
+
+SideBarSizes
+calculateSidebarSizes(const QFont &f);
+}
+
 class Splitter : public QSplitter
 {
         Q_OBJECT
@@ -45,5 +57,5 @@ private:
         int leftMoveCount_  = 0;
         int rightMoveCount_ = 0;
 
-        utils::SideBarSizes sz_;
+        splitter::SideBarSizes sz_;
 };
diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp
index 502456bf..7be50ab5 100644
--- a/src/TextInputWidget.cpp
+++ b/src/TextInputWidget.cpp
@@ -16,12 +16,9 @@
  */
 
 #include <QAbstractTextDocumentLayout>
-#include <QApplication>
 #include <QBuffer>
 #include <QClipboard>
-#include <QDebug>
 #include <QFileDialog>
-#include <QImageReader>
 #include <QMimeData>
 #include <QMimeDatabase>
 #include <QMimeType>
@@ -31,7 +28,7 @@
 
 #include "Cache.h"
 #include "ChatPage.h"
-#include "Config.h"
+#include "Logging.h"
 #include "TextInputWidget.h"
 #include "Utils.h"
 #include "ui/FlatButton.h"
diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h
index 4bdb2509..a430aa5c 100644
--- a/src/TextInputWidget.h
+++ b/src/TextInputWidget.h
@@ -23,7 +23,6 @@
 #include <optional>
 
 #include <QApplication>
-#include <QDebug>
 #include <QHBoxLayout>
 #include <QPaintEvent>
 #include <QTextEdit>
diff --git a/src/TopRoomBar.cpp b/src/TopRoomBar.cpp
index 712fe9aa..ffd57d50 100644
--- a/src/TopRoomBar.cpp
+++ b/src/TopRoomBar.cpp
@@ -15,8 +15,16 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <QDebug>
+#include <QAction>
+#include <QIcon>
+#include <QLabel>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QPen>
+#include <QPoint>
+#include <QStyle>
 #include <QStyleOption>
+#include <QVBoxLayout>
 
 #include "Config.h"
 #include "MainWindow.h"
@@ -210,3 +218,19 @@ TopRoomBar::updateRoomTopic(QString topic)
         topicLabel_->setHtml(topic);
         update();
 }
+
+void
+TopRoomBar::mousePressEvent(QMouseEvent *)
+{
+        if (roomSettings_ != nullptr)
+                roomSettings_->trigger();
+}
+
+void
+TopRoomBar::paintEvent(QPaintEvent *)
+{
+        QStyleOption opt;
+        opt.init(this);
+        QPainter p(this);
+        style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
+}
diff --git a/src/TopRoomBar.h b/src/TopRoomBar.h
index 3243064e..5ab25f39 100644
--- a/src/TopRoomBar.h
+++ b/src/TopRoomBar.h
@@ -17,17 +17,9 @@
 
 #pragma once
 
-#include <QAction>
-#include <QIcon>
-#include <QImage>
-#include <QLabel>
-#include <QPaintEvent>
-#include <QPainter>
-#include <QPen>
-#include <QPoint>
-#include <QStyle>
-#include <QStyleOption>
-#include <QVBoxLayout>
+#include <QColor>
+#include <QStringList>
+#include <QWidget>
 
 class Avatar;
 class FlatButton;
@@ -35,6 +27,12 @@ class Menu;
 class TextLabel;
 class OverlayModal;
 
+class QPainter;
+class QLabel;
+class QIcon;
+class QHBoxLayout;
+class QVBoxLayout;
+
 class TopRoomBar : public QWidget
 {
         Q_OBJECT
@@ -67,19 +65,8 @@ signals:
         void mentionsClicked(const QPoint &pos);
 
 protected:
-        void mousePressEvent(QMouseEvent *) override
-        {
-                if (roomSettings_ != nullptr)
-                        roomSettings_->trigger();
-        }
-
-        void paintEvent(QPaintEvent *) override
-        {
-                QStyleOption opt;
-                opt.init(this);
-                QPainter p(this);
-                style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
-        }
+        void mousePressEvent(QMouseEvent *) override;
+        void paintEvent(QPaintEvent *) override;
 
 private:
         QHBoxLayout *topLayout_  = nullptr;
diff --git a/src/TrayIcon.cpp b/src/TrayIcon.cpp
index 8f62e563..6ab011d1 100644
--- a/src/TrayIcon.cpp
+++ b/src/TrayIcon.cpp
@@ -15,9 +15,11 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QAction>
 #include <QApplication>
 #include <QList>
 #include <QMenu>
+#include <QPainter>
 #include <QTimer>
 
 #include "TrayIcon.h"
diff --git a/src/TrayIcon.h b/src/TrayIcon.h
index a3536cc3..6cb26b87 100644
--- a/src/TrayIcon.h
+++ b/src/TrayIcon.h
@@ -17,13 +17,14 @@
 
 #pragma once
 
-#include <QAction>
 #include <QIcon>
 #include <QIconEngine>
-#include <QPainter>
 #include <QRect>
 #include <QSystemTrayIcon>
 
+class QAction;
+class QPainter;
+
 class MsgCountComposedIcon : public QIconEngine
 {
 public:
diff --git a/src/UserInfoWidget.cpp b/src/UserInfoWidget.cpp
index 7a910340..2e21d41f 100644
--- a/src/UserInfoWidget.cpp
+++ b/src/UserInfoWidget.cpp
@@ -16,14 +16,15 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QPainter>
 #include <QTimer>
 
 #include <iostream>
 
 #include "Config.h"
 #include "MainWindow.h"
+#include "Splitter.h"
 #include "UserInfoWidget.h"
-#include "Utils.h"
 #include "ui/Avatar.h"
 #include "ui/FlatButton.h"
 #include "ui/OverlayModal.h"
@@ -108,7 +109,7 @@ UserInfoWidget::resizeEvent(QResizeEvent *event)
 {
         Q_UNUSED(event);
 
-        const auto sz = utils::calculateSidebarSizes(QFont{});
+        const auto sz = splitter::calculateSidebarSizes(QFont{});
 
         if (width() <= sz.small) {
                 topLayout_->setContentsMargins(0, 0, logoutButtonSize_, 0);
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index b73f80a1..a0f37c26 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -22,6 +22,7 @@
 #include <QLabel>
 #include <QLineEdit>
 #include <QMessageBox>
+#include <QPainter>
 #include <QProcessEnvironment>
 #include <QPushButton>
 #include <QScrollArea>
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 00796a53..55eebbc9 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -22,6 +22,25 @@ using TimelineEvent = mtx::events::collections::TimelineEvents;
 
 QHash<QString, QString> authorColors_;
 
+template<class T, class Event>
+static DescInfo
+createDescriptionInfo(const Event &event, const QString &localUser, const QString &room_id)
+{
+        const auto msg    = std::get<T>(event);
+        const auto sender = QString::fromStdString(msg.sender);
+
+        const auto username = cache::displayName(room_id, sender);
+        const auto ts       = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
+
+        return DescInfo{
+          QString::fromStdString(msg.event_id),
+          sender,
+          utils::messageDescription<T>(
+            username, QString::fromStdString(msg.content.body).trimmed(), sender == localUser),
+          utils::descriptiveTime(ts),
+          ts};
+}
+
 QString
 utils::localUser()
 {
@@ -633,16 +652,3 @@ utils::restoreCombobox(QComboBox *combo, const QString &value)
         }
 }
 
-utils::SideBarSizes
-utils::calculateSidebarSizes(const QFont &f)
-{
-        const auto height = static_cast<double>(QFontMetrics{f}.lineSpacing());
-
-        SideBarSizes sz;
-        sz.small         = std::ceil(3.5 * height + height / 4.0);
-        sz.normal        = std::ceil(16 * height);
-        sz.groups        = std::ceil(3 * height);
-        sz.collapsePoint = 2 * sz.normal;
-
-        return sz;
-}
diff --git a/src/Utils.h b/src/Utils.h
index ea0df21f..a3854dd8 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -2,8 +2,6 @@
 
 #include <variant>
 
-#include "RoomInfoListItem.h"
-
 #include <QCoreApplication>
 #include <QDateTime>
 #include <QPixmap>
@@ -12,6 +10,8 @@
 
 #include <qmath.h>
 
+struct DescInfo;
+
 namespace cache {
 // Forward declarations to prevent dependency on Cache.h, since this header is included often!
 QString
@@ -166,25 +166,6 @@ messageDescription(const QString &username = "",
         }
 }
 
-template<class T, class Event>
-DescInfo
-createDescriptionInfo(const Event &event, const QString &localUser, const QString &room_id)
-{
-        const auto msg    = std::get<T>(event);
-        const auto sender = QString::fromStdString(msg.sender);
-
-        const auto username = cache::displayName(room_id, sender);
-        const auto ts       = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
-
-        return DescInfo{QString::fromStdString(msg.event_id),
-                        sender,
-                        messageDescription<T>(username,
-                                              QString::fromStdString(msg.content.body).trimmed(),
-                                              sender == localUser),
-                        utils::descriptiveTime(ts),
-                        ts};
-}
-
 //! Scale down an image to fit to the given width & height limitations.
 QPixmap
 scaleDown(uint64_t maxWidth, uint64_t maxHeight, const QPixmap &source);
@@ -326,14 +307,4 @@ centerWidget(QWidget *widget, QWidget *parent);
 void
 restoreCombobox(QComboBox *combo, const QString &value);
 
-struct SideBarSizes
-{
-        int small;
-        int normal;
-        int groups;
-        int collapsePoint;
-};
-
-SideBarSizes
-calculateSidebarSizes(const QFont &f);
 }
diff --git a/src/WelcomePage.cpp b/src/WelcomePage.cpp
index 8c3f6487..e4b0e1c6 100644
--- a/src/WelcomePage.cpp
+++ b/src/WelcomePage.cpp
@@ -17,6 +17,7 @@
 
 #include <QLabel>
 #include <QLayout>
+#include <QPainter>
 #include <QStyleOption>
 
 #include "Config.h"
diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp
index dfb3d984..54e7bf96 100644
--- a/src/dialogs/MemberList.cpp
+++ b/src/dialogs/MemberList.cpp
@@ -13,6 +13,7 @@
 #include "Cache.h"
 #include "ChatPage.h"
 #include "Config.h"
+#include "Logging.h"
 #include "Utils.h"
 #include "ui/Avatar.h"
 
@@ -116,7 +117,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent)
         try {
                 addUsers(cache::getMembers(room_id_.toStdString()));
         } catch (const lmdb::error &e) {
-                qCritical() << e.what();
+                nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what());
         }
 
         auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp
index 755e8395..273ffd54 100644
--- a/src/dialogs/UserProfile.cpp
+++ b/src/dialogs/UserProfile.cpp
@@ -1,13 +1,12 @@
 #include <QHBoxLayout>
 #include <QLabel>
 #include <QListWidget>
-#include <QSettings>
 #include <QShortcut>
 #include <QVBoxLayout>
 
-#include "AvatarProvider.h"
 #include "Cache.h"
 #include "ChatPage.h"
+#include "Logging.h"
 #include "MatrixClient.h"
 #include "Utils.h"
 #include "dialogs/UserProfile.h"
diff --git a/src/emoji/ItemDelegate.cpp b/src/emoji/ItemDelegate.cpp
index 890e334a..afa01625 100644
--- a/src/emoji/ItemDelegate.cpp
+++ b/src/emoji/ItemDelegate.cpp
@@ -15,7 +15,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <QDebug>
 #include <QPainter>
 #include <QSettings>
 
diff --git a/src/emoji/Panel.cpp b/src/emoji/Panel.cpp
index 49ff40c5..e3b966b4 100644
--- a/src/emoji/Panel.cpp
+++ b/src/emoji/Panel.cpp
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QPainter>
 #include <QPushButton>
 #include <QScrollBar>
 #include <QVBoxLayout>
diff --git a/src/popups/UserMentions.h b/src/popups/UserMentions.h
index d3877462..42bdcd60 100644
--- a/src/popups/UserMentions.h
+++ b/src/popups/UserMentions.h
@@ -2,19 +2,14 @@
 
 #include <mtx/responses.hpp>
 
-#include <QApplication>
-#include <QEvent>
 #include <QMap>
 #include <QPaintEvent>
 #include <QScrollArea>
-#include <QScrollBar>
 #include <QString>
 #include <QTabWidget>
 #include <QVBoxLayout>
 #include <QWidget>
-#include <Qt>
 
-#include "Logging.h"
 
 namespace popups {
 
@@ -47,4 +42,4 @@ private:
         QScrollArea *all_scroll_area_;
         QWidget *all_scroll_widget_;
 };
-}
\ No newline at end of file
+}
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 44cf79f4..fb32f0fb 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -6,16 +6,18 @@
 #include <QHash>
 #include <QSet>
 
-#include <mtx/common.hpp>
-#include <mtx/responses.hpp>
 #include <mtxclient/http/errors.hpp>
 
 #include "CacheCryptoStructs.h"
-#include "Logging.h"
 
 namespace mtx::http {
 using RequestErr = const std::optional<mtx::http::ClientError> &;
 }
+namespace mtx::responses {
+struct Timeline;
+struct Messages;
+struct ClaimKeys;
+}
 
 namespace qml_mtx_events {
 Q_NAMESPACE
diff --git a/src/ui/DropShadow.cpp b/src/ui/DropShadow.cpp
new file mode 100644
index 00000000..93baa02d
--- /dev/null
+++ b/src/ui/DropShadow.cpp
@@ -0,0 +1,110 @@
+#include "DropShadow.h"
+
+#include <QLinearGradient>
+#include <QPainter>
+
+
+        void DropShadow::draw(QPainter &painter,
+                         qint16 margin,
+                         qreal radius,
+                         QColor start,
+                         QColor end,
+                         qreal startPosition,
+                         qreal endPosition0,
+                         qreal endPosition1,
+                         qreal width,
+                         qreal height)
+        {
+                painter.setPen(Qt::NoPen);
+
+                QLinearGradient gradient;
+                gradient.setColorAt(startPosition, start);
+                gradient.setColorAt(endPosition0, end);
+
+                // Right
+                QPointF right0(width - margin, height / 2);
+                QPointF right1(width, height / 2);
+                gradient.setStart(right0);
+                gradient.setFinalStop(right1);
+                painter.setBrush(QBrush(gradient));
+                // Deprecated in 5.13: painter.drawRoundRect(
+                //  QRectF(QPointF(width - margin * radius, margin), QPointF(width, height -
+                //  margin)), 0.0, 0.0);
+                painter.drawRoundedRect(
+                  QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)),
+                  0.0,
+                  0.0);
+
+                // Left
+                QPointF left0(margin, height / 2);
+                QPointF left1(0, height / 2);
+                gradient.setStart(left0);
+                gradient.setFinalStop(left1);
+                painter.setBrush(QBrush(gradient));
+                painter.drawRoundedRect(
+                  QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0);
+
+                // Top
+                QPointF top0(width / 2, margin);
+                QPointF top1(width / 2, 0);
+                gradient.setStart(top0);
+                gradient.setFinalStop(top1);
+                painter.setBrush(QBrush(gradient));
+                painter.drawRoundedRect(
+                  QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0);
+
+                // Bottom
+                QPointF bottom0(width / 2, height - margin);
+                QPointF bottom1(width / 2, height);
+                gradient.setStart(bottom0);
+                gradient.setFinalStop(bottom1);
+                painter.setBrush(QBrush(gradient));
+                painter.drawRoundedRect(
+                  QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)),
+                  0.0,
+                  0.0);
+
+                // BottomRight
+                QPointF bottomright0(width - margin, height - margin);
+                QPointF bottomright1(width, height);
+                gradient.setStart(bottomright0);
+                gradient.setFinalStop(bottomright1);
+                gradient.setColorAt(endPosition1, end);
+                painter.setBrush(QBrush(gradient));
+                painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0);
+
+                // BottomLeft
+                QPointF bottomleft0(margin, height - margin);
+                QPointF bottomleft1(0, height);
+                gradient.setStart(bottomleft0);
+                gradient.setFinalStop(bottomleft1);
+                gradient.setColorAt(endPosition1, end);
+                painter.setBrush(QBrush(gradient));
+                painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0);
+
+                // TopLeft
+                QPointF topleft0(margin, margin);
+                QPointF topleft1(0, 0);
+                gradient.setStart(topleft0);
+                gradient.setFinalStop(topleft1);
+                gradient.setColorAt(endPosition1, end);
+                painter.setBrush(QBrush(gradient));
+                painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0);
+
+                // TopRight
+                QPointF topright0(width - margin, margin);
+                QPointF topright1(width, 0);
+                gradient.setStart(topright0);
+                gradient.setFinalStop(topright1);
+                gradient.setColorAt(endPosition1, end);
+                painter.setBrush(QBrush(gradient));
+                painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0);
+
+                // Widget
+                painter.setBrush(QBrush("#FFFFFF"));
+                painter.setRenderHint(QPainter::Antialiasing);
+                painter.drawRoundedRect(
+                  QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)),
+                  radius,
+                  radius);
+        }
diff --git a/src/ui/DropShadow.h b/src/ui/DropShadow.h
index 60fc697b..6997e1a0 100644
--- a/src/ui/DropShadow.h
+++ b/src/ui/DropShadow.h
@@ -1,8 +1,8 @@
 #pragma once
 
 #include <QColor>
-#include <QLinearGradient>
-#include <QPainter>
+
+class QPainter;
 
 class DropShadow
 {
@@ -16,99 +16,5 @@ public:
                          qreal endPosition0,
                          qreal endPosition1,
                          qreal width,
-                         qreal height)
-        {
-                painter.setPen(Qt::NoPen);
-
-                QLinearGradient gradient;
-                gradient.setColorAt(startPosition, start);
-                gradient.setColorAt(endPosition0, end);
-
-                // Right
-                QPointF right0(width - margin, height / 2);
-                QPointF right1(width, height / 2);
-                gradient.setStart(right0);
-                gradient.setFinalStop(right1);
-                painter.setBrush(QBrush(gradient));
-                // Deprecated in 5.13: painter.drawRoundRect(
-                //  QRectF(QPointF(width - margin * radius, margin), QPointF(width, height -
-                //  margin)), 0.0, 0.0);
-                painter.drawRoundedRect(
-                  QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)),
-                  0.0,
-                  0.0);
-
-                // Left
-                QPointF left0(margin, height / 2);
-                QPointF left1(0, height / 2);
-                gradient.setStart(left0);
-                gradient.setFinalStop(left1);
-                painter.setBrush(QBrush(gradient));
-                painter.drawRoundedRect(
-                  QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0);
-
-                // Top
-                QPointF top0(width / 2, margin);
-                QPointF top1(width / 2, 0);
-                gradient.setStart(top0);
-                gradient.setFinalStop(top1);
-                painter.setBrush(QBrush(gradient));
-                painter.drawRoundedRect(
-                  QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0);
-
-                // Bottom
-                QPointF bottom0(width / 2, height - margin);
-                QPointF bottom1(width / 2, height);
-                gradient.setStart(bottom0);
-                gradient.setFinalStop(bottom1);
-                painter.setBrush(QBrush(gradient));
-                painter.drawRoundedRect(
-                  QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)),
-                  0.0,
-                  0.0);
-
-                // BottomRight
-                QPointF bottomright0(width - margin, height - margin);
-                QPointF bottomright1(width, height);
-                gradient.setStart(bottomright0);
-                gradient.setFinalStop(bottomright1);
-                gradient.setColorAt(endPosition1, end);
-                painter.setBrush(QBrush(gradient));
-                painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0);
-
-                // BottomLeft
-                QPointF bottomleft0(margin, height - margin);
-                QPointF bottomleft1(0, height);
-                gradient.setStart(bottomleft0);
-                gradient.setFinalStop(bottomleft1);
-                gradient.setColorAt(endPosition1, end);
-                painter.setBrush(QBrush(gradient));
-                painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0);
-
-                // TopLeft
-                QPointF topleft0(margin, margin);
-                QPointF topleft1(0, 0);
-                gradient.setStart(topleft0);
-                gradient.setFinalStop(topleft1);
-                gradient.setColorAt(endPosition1, end);
-                painter.setBrush(QBrush(gradient));
-                painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0);
-
-                // TopRight
-                QPointF topright0(width - margin, margin);
-                QPointF topright1(width, 0);
-                gradient.setStart(topright0);
-                gradient.setFinalStop(topright1);
-                gradient.setColorAt(endPosition1, end);
-                painter.setBrush(QBrush(gradient));
-                painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0);
-
-                // Widget
-                painter.setBrush(QBrush("#FFFFFF"));
-                painter.setRenderHint(QPainter::Antialiasing);
-                painter.drawRoundedRect(
-                  QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)),
-                  radius,
-                  radius);
-        }
+                         qreal height);
 };
diff --git a/src/ui/FlatButton.cpp b/src/ui/FlatButton.cpp
index a828f582..6660c58d 100644
--- a/src/ui/FlatButton.cpp
+++ b/src/ui/FlatButton.cpp
@@ -2,6 +2,8 @@
 #include <QFontDatabase>
 #include <QIcon>
 #include <QMouseEvent>
+#include <QPaintEvent>
+#include <QPainter>
 #include <QPainterPath>
 #include <QResizeEvent>
 #include <QSignalTransition>
diff --git a/src/ui/FlatButton.h b/src/ui/FlatButton.h
index 9c2bf425..d29903c2 100644
--- a/src/ui/FlatButton.h
+++ b/src/ui/FlatButton.h
@@ -1,7 +1,5 @@
 #pragma once
 
-#include <QPaintEvent>
-#include <QPainter>
 #include <QPushButton>
 #include <QStateMachine>
 
diff --git a/src/ui/FloatingButton.cpp b/src/ui/FloatingButton.cpp
index 74dcd482..f3a09ccd 100644
--- a/src/ui/FloatingButton.cpp
+++ b/src/ui/FloatingButton.cpp
@@ -1,3 +1,4 @@
+#include <QPainter>
 #include <QPainterPath>
 
 #include "FloatingButton.h"
diff --git a/src/ui/LoadingIndicator.cpp b/src/ui/LoadingIndicator.cpp
index c8337089..d2b1240d 100644
--- a/src/ui/LoadingIndicator.cpp
+++ b/src/ui/LoadingIndicator.cpp
@@ -1,7 +1,8 @@
 #include "LoadingIndicator.h"
 
-#include <QPoint>
-#include <QtGlobal>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QTimer>
 
 LoadingIndicator::LoadingIndicator(QWidget *parent)
   : QWidget(parent)
diff --git a/src/ui/LoadingIndicator.h b/src/ui/LoadingIndicator.h
index e8de0aec..1585098e 100644
--- a/src/ui/LoadingIndicator.h
+++ b/src/ui/LoadingIndicator.h
@@ -1,11 +1,11 @@
 #pragma once
 
 #include <QColor>
-#include <QPaintEvent>
-#include <QPainter>
-#include <QTimer>
 #include <QWidget>
 
+class QPainter;
+class QTimer;
+class QPaintEvent;
 class LoadingIndicator : public QWidget
 {
         Q_OBJECT
diff --git a/src/ui/OverlayWidget.cpp b/src/ui/OverlayWidget.cpp
index ccac0116..a32d86b6 100644
--- a/src/ui/OverlayWidget.cpp
+++ b/src/ui/OverlayWidget.cpp
@@ -1,5 +1,7 @@
 #include "OverlayWidget.h"
-#include <QEvent>
+
+#include <QPainter>
+#include <QStyleOption>
 
 OverlayWidget::OverlayWidget(QWidget *parent)
   : QWidget(parent)
diff --git a/src/ui/OverlayWidget.h b/src/ui/OverlayWidget.h
index 6662479d..ed3ef52d 100644
--- a/src/ui/OverlayWidget.h
+++ b/src/ui/OverlayWidget.h
@@ -1,10 +1,10 @@
 #pragma once
 
 #include <QEvent>
-#include <QPainter>
-#include <QStyleOption>
 #include <QWidget>
 
+class QPainter;
+
 class OverlayWidget : public QWidget
 {
         Q_OBJECT