#pragma once #include #include #include #include class ChatView; class InputBar; class InputBar; class EmojiPanel; class DbManager; class ChannelList; class AudioRecorder; class MessageList : public QWidget { Q_OBJECT public: explicit MessageList(DbManager* db = nullptr, AudioRecorder* recorder = nullptr, QWidget *parent = nullptr); void loadChannel(const QString& channelId); void refresh(); void reloadLocalNicks(); void saveChannelState(); static void cleanupAnimations(); void updateMessageProgress(const QString& chId, int64_t msgId, int blocksDone, int numBlocks); void onAttachmentDownloaded(const QString& chId, int64_t msgId); void onDmMessages(const uint8_t* data, int len); signals: void readPositionChanged(const QString& channelId, qint64 lastReadMsgId); void openVideoRequested(const QString& filePath); void openImageRequested(const QString& filePath); private: ChatView *m_view; QStandardItemModel *m_model; InputBar *m_inputBar; EmojiPanel *m_emojiPanel; DbManager *m_db; QString m_currentChannelId; bool m_animHoverActive = false; QHash m_avatarCache; qint64 m_lastReadMsgId = 0; QTimer* m_readDebounce; qint64 m_savedTopMsgId = 0; bool m_wasAtBottom = false; QMap m_localNicks; AudioRecorder* m_recorder = nullptr; QString authorName(quint64 nodeId) const; void restoreScrollPosition(const QString& channelId); void updateReadPosition(); void onMessageContextMenu(const QPoint& pos); void requestDmMessages(const QString& channelId); static bool isDmChannel(const QString& channelId); static QString dmConvId(const QString& channelId); };