You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

107 lines
4.3 KiB

/* История и composer выбранного канала/PM: модель сообщений, позиция чтения, загрузки и воспроизведение.
* Применяет события bridge в GUI-потоке; сетевые операции передаёт ядру. */
#pragma once
#include <QWidget>
#include <QStandardItemModel>
#include <QHash>
#include <QTimer>
#include <QSet>
#include <QThreadPool>
#include <QJsonObject>
#include <QPointer>
class ChatView;
class InputBar;
class EmojiPanel;
class DbManager;
class ChannelList;
class AudioRecorder;
class QLabel;
class QPushButton;
class RadioPanel;
class QDialog;
class QMenu;
struct MessageRow;
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);
void refreshDmCallRoute();
void onDmCallRoute(const uint8_t* data, int len);
void clearDmCallRoute();
void onAttachmentPreparation(const uint8_t* data, int len);
void onFeedbackChanged(const uint8_t* data, int len);
void onFeedbackResult(const uint8_t* data, int len);
void onRadioTalk(quint64 groupId, quint64 srcNodeId, bool on); /* индикация говорящего */
signals:
void readPositionChanged(const QString& channelId, qint64 lastReadMsgId);
void callRequested(const QString& target, quint64 peer, const QString& name);
void openVideoRequested(const QString& filePath);
void openImageRequested(const QString& filePath);
void inviteRequested(const QString& sourceChannel, quint64 peer, const QString& name);
void linkActivated(const QString& link);
private:
ChatView *m_view;
QStandardItemModel *m_model;
InputBar *m_inputBar;
EmojiPanel *m_emojiPanel;
DbManager *m_db;
QString m_currentChannelId;
QHash<quint64, QColor> m_avatarCache;
qint64 m_lastReadMsgId = 0;
QTimer* m_readDebounce;
qint64 m_savedTopMsgId = 0;
bool m_wasAtBottom = false;
QMap<quint64, QString> m_localNicks;
AudioRecorder* m_recorder = nullptr;
QLabel* m_peerStatus = nullptr;
QLabel* m_channelTitle = nullptr; /* шапка: название канала */
QLabel* m_talkingLabel = nullptr; /* шапка: кто говорит в рации */
QPushButton* m_callBtn = nullptr;
QPushButton* m_inviteBtn = nullptr;
quint64 m_callPeer = 0;
quint64 m_callGroup = 0;
QPushButton* m_radioBtn = nullptr; /* шапка: переключатель рации */
RadioPanel* m_radioPanel = nullptr; /* верхняя панель устройств, VAD и PTT */
bool m_radioOn = false;
QThreadPool m_thumbnailPool;
QSet<QString> m_thumbnailJobs;
QPushButton* m_pollBtn = nullptr;
QHash<QString, QJsonObject> m_feedback;
QPointer<QDialog> m_pollDialog;
QString m_pollDialogMessage, m_pendingPoll;
quint64 m_feedbackSequence = 0;
void sendFeedback(QJsonObject command, bool userAction = true);
void setupFeedback(QStandardItem* item, const MessageRow& message, const QString& channel);
void createPoll();
void showPoll(const QString& messageId);
void applyFeedback(const QJsonObject& state);
void requestReaction(const QModelIndex& index, int emoji);
void addReactionActions(QMenu* menu, const QString& channel, const QString& messageId);
QString authorName(quint64 nodeId) const;
void restoreScrollPosition(const QString& channelId);
void updateReadPosition();
void onMessageContextMenu(const QPoint& pos);
void requestDmMessages(const QString& channelId);
void prepareVideoThumbnail(const QString& path);
void onRadioToggled(bool on);
void updateRadioUi();
static bool isDmChannel(const QString& channelId);
static QString dmConvId(const QString& channelId);
};