Complete MainWindow and MessageList contracts for commands and snapshots
This commit is contained in:
1 parent
7556695cc5
commit
17772163cd
2 files changed
+68
No files matched your search
@@ -41,14 +41,17 @@ struct AutoPlayItem {
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// db заимствован до деструктора; nullptr создаёт UI без UtunNode. cfgPath — профиль, dbPath — override каталога.
|
||||
explicit MainWindow(QWidget *parent, DbManager* db, const QString& cfgPath,
|
||||
const QString& dbPath = QString(),
|
||||
const QString& debugFile = QString(),
|
||||
const QString& debugLevel = QString(),
|
||||
const QString& debugCategories = QString());
|
||||
// Снять callbacks, остановить media, stop/join node и очистить анимации.
|
||||
~MainWindow() override;
|
||||
|
||||
protected:
|
||||
// Сохранить геометрию и скрыть в tray; для выхода служит requestShutdown.
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private slots:
|
||||
@@ -61,56 +64,92 @@ private slots:
|
||||
void openVideo(const QString& filePath);
|
||||
void openImage(const QString& filePath);
|
||||
void showChannelSettings(const QString& channelId);
|
||||
// Дождаться конца/подготовки player, разрешить путь головы и запустить один voice.
|
||||
void autoPlayTimerTick();
|
||||
|
||||
public:
|
||||
// ch_id задан с длиной; initialSync обновляет историю без уведомления, звука и auto-play.
|
||||
void onMessageReceived(const char* ch_id, int ch_id_len, uint64_t author, bool initialSync);
|
||||
// Передать бинарный CHAT_MEMBER_DISPLAY снимок списку участников и кэшу аватаров.
|
||||
void onMemberList(const QString& chId, int count, const uint8_t* data, int dataLen);
|
||||
// Обновить участника по codec chat_member.h; байты заимствованы до возврата.
|
||||
void onMemberUpdated(const QString& chId, const uint8_t* data);
|
||||
// Удалить nodeId из модели/кэша выбранного chId.
|
||||
void onMemberRemoved(const QString& chId, uint64_t nodeId);
|
||||
// Обновить статус поиска соседей канала.
|
||||
void onAutoConnectStatus(uint8_t status, uint16_t total, uint16_t totalNodes, uint16_t connected);
|
||||
// Обновить online-счётчик ch_id указанной длины.
|
||||
void onChannelPeersOnline(const char* ch_id, int ch_id_len, uint16_t online);
|
||||
// Перечитать список, сбросить исчезнувший target и применить отложенный выбор.
|
||||
void reloadChannels();
|
||||
// Завершение (channel,rowid): разбудить очередь, проверить готовый encrypted voice.
|
||||
void onAttachmentDownloadedForAutoPlay(const QString& chId, int64_t msgId);
|
||||
// Сохранить geometry/read/scroll и поставить stop после этих команд; OOM допускает прямой stop с логом.
|
||||
void requestShutdown();
|
||||
// Заимствованный QObject-владелец ядра либо nullptr; управление — в GUI.
|
||||
UtunNode* utunNode() const { return m_node; }
|
||||
|
||||
/* звонки */
|
||||
// Создать исходящее окно после принятия START мостом; chId может быть dm:<conv_id>.
|
||||
void onCallRequested(const QString& chId, quint64 nodeId, const QString& name);
|
||||
// Показать входящий callId с именем caller из DbManager; повтор ID не создаёт окно.
|
||||
void onCallIncoming(const QString& chId, quint64 caller, quint64 callId);
|
||||
// Обновить состояние существующего исходящего окна и тон.
|
||||
void onCallRinging(quint64 callId);
|
||||
// Активировать callId/audio; при отказе capture послать hangup.
|
||||
void onCallAccepted(quint64 callId);
|
||||
// Завершить audio/окно, при PHONE_BUSY показать причину.
|
||||
void onCallEnded(quint64 callId, uint8_t reason);
|
||||
// Залогировать протокольную ошибку и закрыть окно callId.
|
||||
void onCallError(quint64 callId, uint8_t err);
|
||||
// Обновить диагностический BGP-путь существующего окна.
|
||||
void onCallPath(quint64 callId, const QString& path);
|
||||
// Снять callId из map до deleteLater; повтор безопасен.
|
||||
void closeCallWindow(quint64 callId);
|
||||
// Передать START для CHAT-канала и peer с новым ненулевым ID.
|
||||
void onRadioCallRequested(const QString& channel, quint64 peer);
|
||||
// Применить 27-байтный radio_call event, управлять диалогом/рингтоном и READY/ACCEPT.
|
||||
void onRadioCallEvent(const uint8_t* data, int len);
|
||||
|
||||
/* DM (p2p чат) */
|
||||
// Скопировать общую группу/peer/имя в команду; PM выбирается после DM_CONV_UPDATED.
|
||||
void onPmRequested(const QString& chId, quint64 nodeId, const QString& name);
|
||||
// Открыть отправку свежего invite фиксированному peer; source может быть пустым из PM.
|
||||
void onInviteToPmRequested(const QString& source, quint64 peer, const QString& name);
|
||||
// Разобрать utun/utun-msg ссылку и перейти к доступной группе/оригиналу.
|
||||
void onMessageLinkActivated(const QString& link);
|
||||
// Выбрать только видимое совпавшее поколение истории PM.
|
||||
void onDmConvUpdated(const QString& convId, quint64 generation);
|
||||
// Обновить PM/уведомление; выбранной беседе запросить снимок.
|
||||
void onDmMsgReceived(const QString& convId, quint64 author);
|
||||
// Подтвердить удаление конкретного generation и заблокировать его composer.
|
||||
void onDmDeleteRequested(const QString& convId, quint64 generation, const QString& name);
|
||||
// Применить только зарегистрированный request/conv/generation без очистки новой истории.
|
||||
void onDmDeleteResult(quint64 request, const QString& convId, quint64 generation, bool success);
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
// Поставить owned geometry/maximized/splitter в ui_state.
|
||||
void saveWindowGeometry();
|
||||
// Восстановить размеры в пределах доступных экранов.
|
||||
void restoreWindowGeometry();
|
||||
void setupTray();
|
||||
void showIncomingMessageNotification(const QString& target, quint64 author);
|
||||
// Запустить UtunNode; stopping отсоединяет SQLite до native teardown.
|
||||
void setupNode();
|
||||
void setupMessaging();
|
||||
void setupSoundFromConfig();
|
||||
// Один MainWindow получает bridge events в GUI; деструктор снимает callbacks.
|
||||
void setupBridgeCallbacks();
|
||||
// Связать списки/composer/окна с командами и локальными действиями.
|
||||
void setupConnects();
|
||||
void onShutdownCheck();
|
||||
// Проверить последнюю запись или msgId>0; повторный/свой voice не добавлять.
|
||||
void autoPlayCheckNewMessage(const QString& channelId, qint64 msgId = 0);
|
||||
QString autoPlayMediaDir() const;
|
||||
// Путь обычного voice/проверенного plaintext VOICE; неизвестный encrypted MIME даёт пусто.
|
||||
QString autoPlayFilePath(const QString& channelId, const MessageRow& message) const;
|
||||
// Открыть CHAT browser с owner/общим списком; DM не поддерживается.
|
||||
void showMemberFiles(const QString& channel, quint64 owner = 0);
|
||||
void showStreamPublisher(quint64 group, StreamGridWindow* returnTo = nullptr); // Управление; закрытие возвращает фокус сетке.
|
||||
|
||||
|
||||
@@ -29,33 +29,54 @@ struct MessageRow;
|
||||
class MessageList : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// db/recorder заимствованы; Qt parent владеет виджетом. nullptr db допустим для пустого UI.
|
||||
explicit MessageList(DbManager* db = nullptr, AudioRecorder* recorder = nullptr,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
// Сохранить канал, сменить target; для dm:<id> зафиксировать generation и запросить снимок.
|
||||
void loadChannel(const QString& channelId);
|
||||
// Добавить отсутствующие сообщения (до 200); не вытеснять историческое окно цитаты.
|
||||
void refresh();
|
||||
// Перечитать имена, обновить авторов и превью цитат.
|
||||
void reloadLocalNicks();
|
||||
// Поставить read/верхнюю позицию в ui_state; окно старой цитаты сохраняет свежий watermark.
|
||||
void saveChannelState();
|
||||
// После остановки AnimTimer удалить общие LottieIcon; не вызывать при их отрисовке.
|
||||
static void cleanupAnimations();
|
||||
// Обновить только (chId,msgId) текущей модели без сетевого запроса.
|
||||
void updateMessageProgress(const QString& chId, int64_t msgId, int blocksDone, int numBlocks);
|
||||
// Перечитать путь/роли; отложенный пользовательский play требует прежний target.
|
||||
void onAttachmentDownloaded(const QString& chId, int64_t msgId);
|
||||
// [conv_len,conv,generation,JSON]: чужое/старое поколение не применяется.
|
||||
void onDmMessages(const uint8_t* data, int len);
|
||||
/* Блокировать отправки ожидающего удаления; forget очищает UI только для удалённого поколения и возвращает true. */
|
||||
void setDmDeleting(const QString& convId, quint64 generation, bool deleting);
|
||||
bool forgetDmHistory(const QString& convId, quint64 generation);
|
||||
// Запросить адресата/общую группу; отказ очищает доступность кнопки.
|
||||
void refreshDmCallRoute();
|
||||
// [conv_len,conv,peer,group] только для выбранного PM; group=0 отключает звонок.
|
||||
void onDmCallRoute(const uint8_t* data, int len);
|
||||
// Сбросить peer/group и показать offline.
|
||||
void clearDmCallRoute();
|
||||
// Проверить codec и передать target/job/state composer.
|
||||
void onAttachmentPreparation(const uint8_t* data, int len);
|
||||
// Запросить свежие реакции/опрос для изменённого сообщения текущего канала.
|
||||
void onFeedbackChanged(const uint8_t* data, int len);
|
||||
// Проверить результат/JSON-снимок; чужой канал не меняет модель.
|
||||
void onFeedbackResult(const uint8_t* data, int len);
|
||||
// 9 байт (request_id LE,success) подтверждают/отклоняют зафиксированный черновик.
|
||||
void onMessageSubmitted(const uint8_t* data, int len);
|
||||
// Применить новую версию подписанного item с сохранением scroll и превью ответов.
|
||||
void onMessageUpdated(const uint8_t* data, int len);
|
||||
// Обновить encrypted-вложение и диалог выдачи ключей текущего канала.
|
||||
void onAttachmentKeysChanged(const uint8_t* data, int len);
|
||||
void onRadioTalk(quint64 groupId, quint64 srcNodeId, bool on); /* индикация говорящего */
|
||||
bool enableRadio(); /* идемпотентное включение рации выбранного канала, false при ошибке аудио */
|
||||
// Применить проверенный полный каталог выбранной CHAT-группы.
|
||||
void onStreamSources(const uint8_t* data, int len);
|
||||
// Очистить каталог/кнопку remote streams.
|
||||
void clearStreams();
|
||||
// Наблюдать CHAT-группу; пустой target/PM передаёт 0 и снимает наблюдение.
|
||||
void watchStreams();
|
||||
/* Показывает кнопку своей публикации во всех каналах; group=0 скрывает после завершения. GUI-поток. */
|
||||
void setStreamPublisherGroup(quint64 group);
|
||||
@@ -121,11 +142,14 @@ private:
|
||||
QByteArray m_historyAnchor;
|
||||
void updateReply(QStandardItem* item, const QByteArray& original);
|
||||
void refreshReplies();
|
||||
// Разрешить подписанный ID в выбранном канале, загрузить окно и подсветить оригинал.
|
||||
void jumpToMessage(const QString& messageId);
|
||||
|
||||
bool sendFeedback(QJsonObject command, bool userAction = true); // true — запрос принят; ch фиксируется до модального UI.
|
||||
void setupFeedback(QStandardItem* item, const MessageRow& message, const QString& channel);
|
||||
// Проверить UTF-8 лимиты и передать опрос в исходный канал диалога.
|
||||
void createPoll();
|
||||
// Показать один диалог опроса или запросить недостающий снимок.
|
||||
void showPoll(const QString& messageId);
|
||||
void applyFeedback(const QJsonObject& state);
|
||||
void requestReaction(const QModelIndex& index, int emoji);
|
||||
@@ -133,10 +157,15 @@ private:
|
||||
|
||||
QString authorName(quint64 nodeId) const;
|
||||
void restoreScrollPosition(const QString& channelId);
|
||||
// Максимальный rowid полностью видимых строк; watermark меняется после принятия записи.
|
||||
void updateReadPosition();
|
||||
// Persistent index/QPointer защищают menu от замены модели/уничтожения UI.
|
||||
void onMessageContextMenu(const QPoint& pos);
|
||||
// Запросить выбранное поколение PM; ожидающее удаление блокирует запрос.
|
||||
void requestDmMessages(const QString& channelId);
|
||||
// Не более двух FFmpeg jobs; GUI callback защищён QPointer.
|
||||
void prepareVideoThumbnail(const QString& path);
|
||||
// Owned-подписка в uasync и local audio; ошибка восстанавливает кнопку.
|
||||
void onRadioToggled(bool on);
|
||||
void updateRadioUi();
|
||||
static bool isDmChannel(const QString& channelId);
|
||||
|
||||
Reference in new issue
Block a user