From 19b758591b2ab75fb0525bb87636a54a4788029c Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:44:48 -0800 Subject: [PATCH] Allow offline Replays tab (#5519) --- cockatrice/src/client/tabs/tab_replays.cpp | 36 ++++++++++++++++++- cockatrice/src/client/tabs/tab_replays.h | 9 ++++- cockatrice/src/client/tabs/tab_supervisor.cpp | 14 ++------ .../remote/remote_replay_list_tree_widget.cpp | 16 +++++++-- .../remote/remote_replay_list_tree_widget.h | 7 +++- 5 files changed, 65 insertions(+), 17 deletions(-) diff --git a/cockatrice/src/client/tabs/tab_replays.cpp b/cockatrice/src/client/tabs/tab_replays.cpp index 8382c1c39..8c023d671 100644 --- a/cockatrice/src/client/tabs/tab_replays.cpp +++ b/cockatrice/src/client/tabs/tab_replays.cpp @@ -27,7 +27,8 @@ #include #include -TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client) : Tab(_tabSupervisor), client(_client) +TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User *currentUserInfo) + : Tab(_tabSupervisor), client(_client) { localDirModel = new QFileSystemModel(this); localDirModel->setRootPath(SettingsCache::instance().getReplaysPath()); @@ -147,6 +148,10 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client) : connect(client, SIGNAL(replayAddedEventReceived(const Event_ReplayAdded &)), this, SLOT(replayAddedEventReceived(const Event_ReplayAdded &))); + + connect(client, &AbstractClient::userInfoChanged, this, &TabReplays::handleConnected); + connect(client, &AbstractClient::statusChanged, this, &TabReplays::handleConnectionChanged); + setRemoteEnabled(currentUserInfo && currentUserInfo->user_level() & ServerInfo_User::IsRegistered); } void TabReplays::retranslateUi() @@ -165,6 +170,35 @@ void TabReplays::retranslateUi() aDeleteRemoteReplay->setText(tr("Delete")); } +void TabReplays::handleConnected(const ServerInfo_User &userInfo) +{ + setRemoteEnabled(userInfo.user_level() & ServerInfo_User::IsRegistered); +} + +/** + * This is only responsible for handling the disconnect. The connect is already handled elsewhere + */ +void TabReplays::handleConnectionChanged(ClientStatus status) +{ + if (status == StatusDisconnected) { + setRemoteEnabled(false); + } +} + +void TabReplays::setRemoteEnabled(bool enabled) +{ + aOpenRemoteReplay->setEnabled(enabled); + aDownload->setEnabled(enabled); + aKeep->setEnabled(enabled); + aDeleteRemoteReplay->setEnabled(enabled); + + if (enabled) { + serverDirView->refreshTree(); + } else { + serverDirView->clearTree(); + } +} + void TabReplays::actLocalDoubleClick(const QModelIndex &curLeft) { if (!localDirModel->isDir(curLeft)) { diff --git a/cockatrice/src/client/tabs/tab_replays.h b/cockatrice/src/client/tabs/tab_replays.h index 187d2078b..3926710a8 100644 --- a/cockatrice/src/client/tabs/tab_replays.h +++ b/cockatrice/src/client/tabs/tab_replays.h @@ -1,8 +1,10 @@ #ifndef TAB_REPLAYS_H #define TAB_REPLAYS_H +#include "../game_logic/abstract_client.h" #include "tab.h" +class ServerInfo_User; class Response; class AbstractClient; class QTreeView; @@ -29,9 +31,14 @@ private: QAction *aOpenReplaysFolder; QAction *aOpenRemoteReplay, *aDownload, *aKeep, *aDeleteRemoteReplay; + void setRemoteEnabled(bool enabled); + void downloadNodeAtIndex(const QModelIndex &curLeft, const QModelIndex &curRight); private slots: + void handleConnected(const ServerInfo_User &userInfo); + void handleConnectionChanged(ClientStatus status); + void actLocalDoubleClick(const QModelIndex &curLeft); void actRenameLocal(); void actOpenLocalReplay(); @@ -58,7 +65,7 @@ signals: void openReplay(GameReplay *replay); public: - TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client); + TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User *currentUserInfo); void retranslateUi() override; QString getTabText() const override { diff --git a/cockatrice/src/client/tabs/tab_supervisor.cpp b/cockatrice/src/client/tabs/tab_supervisor.cpp index a704fb8b1..123f77bf1 100644 --- a/cockatrice/src/client/tabs/tab_supervisor.cpp +++ b/cockatrice/src/client/tabs/tab_supervisor.cpp @@ -280,6 +280,7 @@ void TabSupervisor::initStartupTabs() checkAndTrigger(aTabVisualDeckStorage, SettingsCache::instance().getTabVisualDeckStorageOpen()); checkAndTrigger(aTabDeckStorage, SettingsCache::instance().getTabDeckStorageOpen()); + checkAndTrigger(aTabReplays, SettingsCache::instance().getTabReplaysOpen()); } /** @@ -336,6 +337,7 @@ void TabSupervisor::resetTabsMenu() tabsMenu->addSeparator(); tabsMenu->addAction(aTabVisualDeckStorage); tabsMenu->addAction(aTabDeckStorage); + tabsMenu->addAction(aTabReplays); } void TabSupervisor::start(const ServerInfo_User &_userInfo) @@ -356,12 +358,6 @@ void TabSupervisor::start(const ServerInfo_User &_userInfo) updatePingTime(0, -1); - if (userInfo->user_level() & ServerInfo_User::IsRegistered) { - tabsMenu->addAction(aTabReplays); - - checkAndTrigger(aTabReplays, SettingsCache::instance().getTabReplaysOpen()); - } - if (userInfo->user_level() & ServerInfo_User::IsModerator) { tabsMenu->addSeparator(); tabsMenu->addAction(aTabAdmin); @@ -379,7 +375,6 @@ void TabSupervisor::startLocal(const QList &_clients) resetTabsMenu(); tabAccount = nullptr; - tabReplays = nullptr; tabAdmin = nullptr; tabLog = nullptr; isLocalGame = true; @@ -415,9 +410,6 @@ void TabSupervisor::stop() if (tabServer) { tabServer->closeRequest(true); } - if (tabReplays) { - tabReplays->closeRequest(true); - } if (tabAdmin) { tabAdmin->closeRequest(true); } @@ -520,7 +512,7 @@ void TabSupervisor::actTabReplays(bool checked) { SettingsCache::instance().setTabReplaysOpen(checked); if (checked && !tabReplays) { - tabReplays = new TabReplays(this, client); + tabReplays = new TabReplays(this, client, userInfo); connect(tabReplays, &TabReplays::openReplay, this, &TabSupervisor::openReplay); myAddTab(tabReplays, aTabReplays); connect(tabReplays, &Tab::closed, this, [this] { diff --git a/cockatrice/src/server/remote/remote_replay_list_tree_widget.cpp b/cockatrice/src/server/remote/remote_replay_list_tree_widget.cpp index 3f58d898a..e75df12b2 100644 --- a/cockatrice/src/server/remote/remote_replay_list_tree_widget.cpp +++ b/cockatrice/src/server/remote/remote_replay_list_tree_widget.cpp @@ -43,7 +43,7 @@ RemoteReplayList_TreeModel::RemoteReplayList_TreeModel(AbstractClient *_client, RemoteReplayList_TreeModel::~RemoteReplayList_TreeModel() { - clearTree(); + clearAll(); } int RemoteReplayList_TreeModel::rowCount(const QModelIndex &parent) const @@ -242,7 +242,10 @@ ServerInfo_ReplayMatch const *RemoteReplayList_TreeModel::getEnclosingReplayMatc return &node->getMatchInfo(); } -void RemoteReplayList_TreeModel::clearTree() +/** + * Deletes all items in the model + */ +void RemoteReplayList_TreeModel::clearAll() { for (int i = 0; i < replayMatches.size(); ++i) delete replayMatches[i]; @@ -258,6 +261,13 @@ void RemoteReplayList_TreeModel::refreshTree() client->sendCommand(pend); } +void RemoteReplayList_TreeModel::clearTree() +{ + beginResetModel(); + clearAll(); + endResetModel(); +} + void RemoteReplayList_TreeModel::addMatchInfo(const ServerInfo_ReplayMatch &matchInfo) { beginInsertRows(QModelIndex(), replayMatches.size(), replayMatches.size()); @@ -294,7 +304,7 @@ void RemoteReplayList_TreeModel::replayListFinished(const Response &r) const Response_ReplayList &resp = r.GetExtension(Response_ReplayList::ext); beginResetModel(); - clearTree(); + clearAll(); for (int i = 0; i < resp.match_list_size(); ++i) replayMatches.append(new MatchNode(resp.match_list(i))); diff --git a/cockatrice/src/server/remote/remote_replay_list_tree_widget.h b/cockatrice/src/server/remote/remote_replay_list_tree_widget.h index f64d87857..ff5a5f303 100644 --- a/cockatrice/src/server/remote/remote_replay_list_tree_widget.h +++ b/cockatrice/src/server/remote/remote_replay_list_tree_widget.h @@ -73,7 +73,7 @@ private: QList replayMatches; QIcon dirIcon, fileIcon, lockIcon; - void clearTree(); + void clearAll(); static const int numberOfColumns; signals: @@ -94,6 +94,7 @@ public: QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; Qt::ItemFlags flags(const QModelIndex &index) const; + void clearTree(); void refreshTree(); ServerInfo_Replay const *getReplay(const QModelIndex &index) const; ServerInfo_ReplayMatch const *getReplayMatch(const QModelIndex &index) const; @@ -115,6 +116,10 @@ public: ServerInfo_ReplayMatch const *getReplayMatch(const QModelIndex &ind) const; QList getSelectedReplays() const; QSet getSelectedReplayMatches() const; + void clearTree() + { + treeModel->clearTree(); + } void refreshTree() { treeModel->refreshTree();