Support downloading replay folders (#5325)

* rename old get replay match method to get enclosing

* creat raw getReplayMatch method

* implement thing
This commit is contained in:
RickyRister 2024-12-25 04:33:36 -08:00 committed by GitHub
parent 9d7fd66546
commit ed907d7c6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 18 deletions

View file

@ -239,30 +239,36 @@ void TabReplays::openRemoteReplayFinished(const Response &r)
void TabReplays::actDownload() void TabReplays::actDownload()
{ {
QString dirPath;
QModelIndex curLeft = localDirView->selectionModel()->currentIndex(); QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
if (!curLeft.isValid()) while (!localDirModel->isDir(curLeft)) {
dirPath = localDirModel->rootPath(); curLeft = curLeft.parent();
else {
while (!localDirModel->isDir(curLeft))
curLeft = curLeft.parent();
dirPath = localDirModel->filePath(curLeft);
} }
const auto curRights = serverDirView->getSelectedReplays(); for (const auto curRight : serverDirView->selectionModel()->selectedRows()) {
downloadNodeAtIndex(curLeft, curRight);
const auto isNull = [](const auto *replay) { return !replay; };
if (std::any_of(curRights.begin(), curRights.end(), isNull)) {
QMessageBox::information(this, tr("Downloading Replays"),
tr("Folder download is not yet supported. Please download replays individually."));
return;
} }
}
for (const auto curRight : curRights) { void TabReplays::downloadNodeAtIndex(const QModelIndex &curLeft, const QModelIndex &curRight)
const QString filePath = dirPath + QString("/replay_%1.cor").arg(curRight->replay_id()); {
if (const auto replayMatch = serverDirView->getReplayMatch(curRight)) {
// node at index is a folder
const QString name =
QString::number(replayMatch->game_id()) + "_" + QString::fromStdString(replayMatch->game_name());
const auto newDirIndex = localDirModel->mkdir(curLeft, name);
int rows = serverDirView->model()->rowCount(curRight);
for (int i = 0; i < rows; i++) {
const auto childIndex = serverDirView->model()->index(i, 0, curRight);
downloadNodeAtIndex(newDirIndex, childIndex);
}
} else if (const auto replay = serverDirView->getReplay(curRight)) {
// node at index is a replay
const QString filePath = localDirModel->filePath(curLeft) + QString("/replay_%1.cor").arg(replay->replay_id());
Command_ReplayDownload cmd; Command_ReplayDownload cmd;
cmd.set_replay_id(curRight->replay_id()); cmd.set_replay_id(replay->replay_id());
PendingCommand *pend = client->prepareSessionCommand(cmd); PendingCommand *pend = client->prepareSessionCommand(cmd);
pend->setExtraData(filePath); pend->setExtraData(filePath);
@ -270,6 +276,7 @@ void TabReplays::actDownload()
SLOT(downloadFinished(Response, CommandContainer, QVariant))); SLOT(downloadFinished(Response, CommandContainer, QVariant)));
client->sendCommand(pend); client->sendCommand(pend);
} }
// node at index was invalid
} }
void TabReplays::downloadFinished(const Response &r, void TabReplays::downloadFinished(const Response &r,

View file

@ -27,6 +27,9 @@ private:
QAction *aOpenLocalReplay, *aNewLocalFolder, *aDeleteLocalReplay; QAction *aOpenLocalReplay, *aNewLocalFolder, *aDeleteLocalReplay;
QAction *aOpenRemoteReplay, *aDownload, *aKeep, *aDeleteRemoteReplay; QAction *aOpenRemoteReplay, *aDownload, *aKeep, *aDeleteRemoteReplay;
void downloadNodeAtIndex(const QModelIndex &curLeft, const QModelIndex &curRight);
private slots: private slots:
void actLocalDoubleClick(const QModelIndex &curLeft); void actLocalDoubleClick(const QModelIndex &curLeft);
void actOpenLocalReplay(); void actOpenLocalReplay();

View file

@ -216,6 +216,18 @@ ServerInfo_Replay const *RemoteReplayList_TreeModel::getReplay(const QModelIndex
} }
ServerInfo_ReplayMatch const *RemoteReplayList_TreeModel::getReplayMatch(const QModelIndex &index) const ServerInfo_ReplayMatch const *RemoteReplayList_TreeModel::getReplayMatch(const QModelIndex &index) const
{
if (!index.isValid())
return nullptr;
auto *node = dynamic_cast<MatchNode *>(static_cast<Node *>(index.internalPointer()));
if (!node)
return nullptr;
return &node->getMatchInfo();
}
ServerInfo_ReplayMatch const *RemoteReplayList_TreeModel::getEnclosingReplayMatch(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return nullptr; return nullptr;
@ -318,6 +330,15 @@ ServerInfo_Replay const *RemoteReplayList_TreeWidget::getReplay(const QModelInde
return treeModel->getReplay(proxyModel->mapToSource(ind)); return treeModel->getReplay(proxyModel->mapToSource(ind));
} }
/**
* Gets the replay match at the given index
* @return The replay match. Returns nullptr if there is no replay match at the index.
*/
ServerInfo_ReplayMatch const *RemoteReplayList_TreeWidget::getReplayMatch(const QModelIndex &ind) const
{
return treeModel->getReplayMatch(proxyModel->mapToSource(ind));
}
/** /**
* Gets all currently selected replays. * Gets all currently selected replays.
* Any selection that isn't a replay file (e.g. a folder) will appear as a nullptr in the list. * Any selection that isn't a replay file (e.g. a folder) will appear as a nullptr in the list.
@ -338,6 +359,7 @@ QList<ServerInfo_Replay const *> RemoteReplayList_TreeWidget::getSelectedReplays
/** /**
* Gets all currently selected replayMatches. * Gets all currently selected replayMatches.
* If a non-folder node is selected, it will return the parent folder of that node.
* *
* @return A Set of pointers to the selected replayMatches. * @return A Set of pointers to the selected replayMatches.
*/ */
@ -346,7 +368,7 @@ QSet<ServerInfo_ReplayMatch const *> RemoteReplayList_TreeWidget::getSelectedRep
const auto selection = selectionModel()->selectedRows(); const auto selection = selectionModel()->selectedRows();
auto replayMatches = QSet<ServerInfo_ReplayMatch const *>(); auto replayMatches = QSet<ServerInfo_ReplayMatch const *>();
for (const auto &row : selection) { for (const auto &row : selection) {
if (const auto replayMatch = treeModel->getReplayMatch(proxyModel->mapToSource(row))) { if (const auto replayMatch = treeModel->getEnclosingReplayMatch(proxyModel->mapToSource(row))) {
replayMatches << replayMatch; replayMatches << replayMatch;
} }
} }

View file

@ -97,6 +97,7 @@ public:
void refreshTree(); void refreshTree();
ServerInfo_Replay const *getReplay(const QModelIndex &index) const; ServerInfo_Replay const *getReplay(const QModelIndex &index) const;
ServerInfo_ReplayMatch const *getReplayMatch(const QModelIndex &index) const; ServerInfo_ReplayMatch const *getReplayMatch(const QModelIndex &index) const;
ServerInfo_ReplayMatch const *getEnclosingReplayMatch(const QModelIndex &index) const;
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo); void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo);
void updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo); void updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo);
void removeMatchInfo(int gameId); void removeMatchInfo(int gameId);
@ -111,6 +112,7 @@ private:
public: public:
RemoteReplayList_TreeWidget(AbstractClient *_client, QWidget *parent = nullptr); RemoteReplayList_TreeWidget(AbstractClient *_client, QWidget *parent = nullptr);
ServerInfo_Replay const *getReplay(const QModelIndex &ind) const; ServerInfo_Replay const *getReplay(const QModelIndex &ind) const;
ServerInfo_ReplayMatch const *getReplayMatch(const QModelIndex &ind) const;
QList<ServerInfo_Replay const *> getSelectedReplays() const; QList<ServerInfo_Replay const *> getSelectedReplays() const;
QSet<ServerInfo_ReplayMatch const *> getSelectedReplayMatches() const; QSet<ServerInfo_ReplayMatch const *> getSelectedReplayMatches() const;
void refreshTree(); void refreshTree();