[DeckShare] Recover the share controls when the server never answers

This commit is contained in:
Lukas Brübach 2026-09-19 00:03:51 +02:00
parent e6d6cbde1e
commit fdc43f623a
6 changed files with 62 additions and 2 deletions

View file

@ -8,6 +8,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include <QTimer>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <libcockatrice/card/database/card_database_manager.h> #include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/deck_list.h> #include <libcockatrice/deck_list/deck_list.h>
@ -17,8 +18,10 @@
#include <libcockatrice/protocol/pb/response_deck_share_create.pb.h> #include <libcockatrice/protocol/pb/response_deck_share_create.pb.h>
#include <libcockatrice/protocol/pending_command.h> #include <libcockatrice/protocol/pending_command.h>
#include "../../../client/settings/cache_settings.h"
DlgShareDeck::DlgShareDeck(AbstractClient *_client, const QSharedPointer<DeckList> &_deck, QWidget *_parent) DlgShareDeck::DlgShareDeck(AbstractClient *_client, const QSharedPointer<DeckList> &_deck, QWidget *_parent)
: QDialog(_parent), client(_client), deck(_deck) : QDialog(_parent), client(_client), deck(_deck), shareTimeoutTimer(new QTimer(this))
{ {
setWindowTitle(tr("Share deck")); setWindowTitle(tr("Share deck"));
@ -38,6 +41,12 @@ DlgShareDeck::DlgShareDeck(AbstractClient *_client, const QSharedPointer<DeckLis
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgShareDeck::reject); connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgShareDeck::reject);
this->buttonBox = buttonBox; this->buttonBox = buttonBox;
layout->addWidget(buttonBox); layout->addWidget(buttonBox);
shareTimeoutTimer->setSingleShot(true);
shareTimeoutTimer->setInterval(
static_cast<int>((static_cast<qint64>(SettingsCache::instance().network().getTimeOut()) + 1) *
SettingsCache::instance().network().getKeepAlive() * 1000));
connect(shareTimeoutTimer, &QTimer::timeout, this, &DlgShareDeck::onShareTimeout);
} }
void DlgShareDeck::actShare() void DlgShareDeck::actShare()
@ -57,10 +66,12 @@ void DlgShareDeck::actShare()
PendingCommand *pend = client->prepareSessionCommand(cmd); PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, &PendingCommand::finished, this, &DlgShareDeck::shareFinished); connect(pend, &PendingCommand::finished, this, &DlgShareDeck::shareFinished);
client->sendCommand(pend); client->sendCommand(pend);
shareTimeoutTimer->start();
} }
void DlgShareDeck::shareFinished(const Response &response, const CommandContainer & /*commandContainer*/) void DlgShareDeck::shareFinished(const Response &response, const CommandContainer & /*commandContainer*/)
{ {
shareTimeoutTimer->stop();
if (response.response_code() != Response::RespOk) { if (response.response_code() != Response::RespOk) {
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
QMessageBox::critical(this, tr("Share deck"), QMessageBox::critical(this, tr("Share deck"),
@ -76,4 +87,10 @@ void DlgShareDeck::shareFinished(const Response &response, const CommandContaine
"The share expires on %2.") "The share expires on %2.")
.arg(share.link, DeckShareUtils::formatShareExpiry(share.expiry))); .arg(share.link, DeckShareUtils::formatShareExpiry(share.expiry)));
accept(); accept();
}
void DlgShareDeck::onShareTimeout()
{
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
QMessageBox::warning(this, tr("Share deck"), tr("The server did not respond in time. Try again."));
} }

View file

@ -15,6 +15,7 @@ class CommandContainer;
class DeckList; class DeckList;
class QDialogButtonBox; class QDialogButtonBox;
class QLineEdit; class QLineEdit;
class QTimer;
class Response; class Response;
/** /**
@ -32,12 +33,14 @@ public:
private slots: private slots:
void actShare(); void actShare();
void shareFinished(const Response &response, const CommandContainer &commandContainer); void shareFinished(const Response &response, const CommandContainer &commandContainer);
void onShareTimeout();
private: private:
AbstractClient *client; AbstractClient *client;
QSharedPointer<DeckList> deck; QSharedPointer<DeckList> deck;
QLineEdit *nameEdit; QLineEdit *nameEdit;
QDialogButtonBox *buttonBox; QDialogButtonBox *buttonBox;
QTimer *shareTimeoutTimer;
}; };
#endif // DLG_SHARE_DECK_H #endif // DLG_SHARE_DECK_H

View file

@ -22,6 +22,7 @@
#include <QMessageBox> #include <QMessageBox>
#include <QToolBar> #include <QToolBar>
#include <QTreeView> #include <QTreeView>
#include <QTimer>
#include <QUrl> #include <QUrl>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <libcockatrice/deck_list/deck_list.h> #include <libcockatrice/deck_list/deck_list.h>
@ -108,6 +109,13 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
connect(shareBar, &ShareBarWidget::cancelRequested, this, &TabDeckStorage::cancelShareDecks); connect(shareBar, &ShareBarWidget::cancelRequested, this, &TabDeckStorage::cancelShareDecks);
shareBar->setVisible(false); shareBar->setVisible(false);
shareTimeoutTimer = new QTimer(this);
shareTimeoutTimer->setSingleShot(true);
shareTimeoutTimer->setInterval(
static_cast<int>((static_cast<qint64>(SettingsCache::instance().network().getTimeOut()) + 1) *
SettingsCache::instance().network().getKeepAlive() * 1000));
connect(shareTimeoutTimer, &QTimer::timeout, this, &TabDeckStorage::onShareFromTreeTimeout);
QVBoxLayout *rightVbox = new QVBoxLayout; QVBoxLayout *rightVbox = new QVBoxLayout;
rightVbox->addWidget(shareBar); rightVbox->addWidget(shareBar);
rightVbox->addWidget(serverDirView); rightVbox->addWidget(serverDirView);
@ -765,10 +773,12 @@ void TabDeckStorage::actShareSelection()
PendingCommand *pend = client->prepareSessionCommand(cmd); PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::shareFromTreeFinished); connect(pend, &PendingCommand::finished, this, &TabDeckStorage::shareFromTreeFinished);
client->sendCommand(pend); client->sendCommand(pend);
shareTimeoutTimer->start();
} }
void TabDeckStorage::shareFromTreeFinished(const Response &response, const CommandContainer & /*commandContainer*/) void TabDeckStorage::shareFromTreeFinished(const Response &response, const CommandContainer & /*commandContainer*/)
{ {
shareTimeoutTimer->stop();
shareBar->setCreateEnabled(true); shareBar->setCreateEnabled(true);
if (response.response_code() != Response::RespOk) { if (response.response_code() != Response::RespOk) {
qWarning() << "failed to create deck share:" << response.response_code(); qWarning() << "failed to create deck share:" << response.response_code();
@ -790,3 +800,9 @@ void TabDeckStorage::showShareNotice(const QString &message, bool warning)
QMessageBox::Ok, this); QMessageBox::Ok, this);
box.exec(); box.exec();
} }
void TabDeckStorage::onShareFromTreeTimeout()
{
shareBar->setCreateEnabled(true);
showShareNotice(tr("The server did not respond in time. Try again."), true);
}

View file

@ -22,6 +22,7 @@ class QToolBar;
class QTreeWidget; class QTreeWidget;
class QTreeWidgetItem; class QTreeWidgetItem;
class QGroupBox; class QGroupBox;
class QTimer;
class CommandContainer; class CommandContainer;
class Response; class Response;
class ShareBarWidget; class ShareBarWidget;
@ -37,6 +38,7 @@ private:
RemoteDeckList_TreeWidget *serverDirView; RemoteDeckList_TreeWidget *serverDirView;
QGroupBox *leftGroupBox, *rightGroupBox; QGroupBox *leftGroupBox, *rightGroupBox;
ShareBarWidget *shareBar; ShareBarWidget *shareBar;
QTimer *shareTimeoutTimer;
QAction *aOpenLocalDeck, *aRenameLocal, *aUpload, *aNewLocalFolder, *aDeleteLocalDeck; QAction *aOpenLocalDeck, *aRenameLocal, *aUpload, *aNewLocalFolder, *aDeleteLocalDeck;
QAction *aOpenDecksFolder; QAction *aOpenDecksFolder;
@ -86,6 +88,7 @@ private slots:
void cancelShareDecks(); void cancelShareDecks();
void onServerSelectionChanged(); void onServerSelectionChanged();
void shareFromTreeFinished(const Response &r, const CommandContainer &commandContainer); void shareFromTreeFinished(const Response &r, const CommandContainer &commandContainer);
void onShareFromTreeTimeout();
void actDeleteRemoteDeck(); void actDeleteRemoteDeck();
void deleteFolderFinished(const Response &response, const CommandContainer &commandContainer); void deleteFolderFinished(const Response &response, const CommandContainer &commandContainer);

View file

@ -7,6 +7,7 @@
#include "../tab_supervisor.h" #include "../tab_supervisor.h"
#include <QMessageBox> #include <QMessageBox>
#include <QTimer>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <libcockatrice/card/database/card_database_manager.h> #include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/deck_list.h> #include <libcockatrice/deck_list/deck_list.h>
@ -16,8 +17,11 @@
#include <libcockatrice/protocol/pb/response_deck_share_create.pb.h> #include <libcockatrice/protocol/pb/response_deck_share_create.pb.h>
#include <libcockatrice/protocol/pending_command.h> #include <libcockatrice/protocol/pending_command.h>
#include "../../../client/settings/cache_settings.h"
TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor, AbstractClient *_client) TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor, AbstractClient *_client)
: Tab(_tabSupervisor), client(_client), visualDeckStorageWidget(new VisualDeckStorageWidget(this)) : Tab(_tabSupervisor), client(_client), visualDeckStorageWidget(new VisualDeckStorageWidget(this)),
shareTimeoutTimer(new QTimer(this))
{ {
connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::openDeckInNewTab); connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::openDeckInNewTab);
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckLoadRequested, this, connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckLoadRequested, this,
@ -53,6 +57,12 @@ TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor, Abstra
layout->insertWidget(0, shareBar); layout->insertWidget(0, shareBar);
shareBar->setVisible(false); shareBar->setVisible(false);
shareTimeoutTimer->setSingleShot(true);
shareTimeoutTimer->setInterval(
static_cast<int>((static_cast<qint64>(SettingsCache::instance().network().getTimeOut()) + 1) *
SettingsCache::instance().network().getKeepAlive() * 1000));
connect(shareTimeoutTimer, &QTimer::timeout, this, &TabDeckStorageVisual::onShareTimeout);
retranslateUi(); retranslateUi();
} }
@ -153,10 +163,12 @@ void TabDeckStorageVisual::actShareSelected()
PendingCommand *pend = client->prepareSessionCommand(cmd); PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, &PendingCommand::finished, this, &TabDeckStorageVisual::shareFinished); connect(pend, &PendingCommand::finished, this, &TabDeckStorageVisual::shareFinished);
client->sendCommand(pend); client->sendCommand(pend);
shareTimeoutTimer->start();
} }
void TabDeckStorageVisual::shareFinished(const Response &response, const CommandContainer & /*commandContainer*/) void TabDeckStorageVisual::shareFinished(const Response &response, const CommandContainer & /*commandContainer*/)
{ {
shareTimeoutTimer->stop();
shareBar->setCreateEnabled(true); shareBar->setCreateEnabled(true);
if (response.response_code() != Response::RespOk) { if (response.response_code() != Response::RespOk) {
showShareNotice(tr("Failed to create the share link (server response code %1).") showShareNotice(tr("Failed to create the share link (server response code %1).")
@ -186,4 +198,10 @@ void TabDeckStorageVisual::showShareNotice(const QString &message, bool warning)
QMessageBox box(warning ? QMessageBox::Warning : QMessageBox::Information, tr("Deck share"), message, QMessageBox box(warning ? QMessageBox::Warning : QMessageBox::Information, tr("Deck share"), message,
QMessageBox::Ok, this); QMessageBox::Ok, this);
box.exec(); box.exec();
}
void TabDeckStorageVisual::onShareTimeout()
{
shareBar->setCreateEnabled(true);
showShareNotice(tr("The server did not respond in time. Try again."), true);
} }

View file

@ -19,6 +19,7 @@ class CommandContainer;
class DeckPreviewWidget; class DeckPreviewWidget;
class QFileSystemModel; class QFileSystemModel;
class QGroupBox; class QGroupBox;
class QTimer;
class QToolBar; class QToolBar;
class QTreeView; class QTreeView;
class QTreeWidget; class QTreeWidget;
@ -63,6 +64,7 @@ signals:
private slots: private slots:
void actShareSelected(); void actShareSelected();
void shareFinished(const Response &response, const CommandContainer &commandContainer); void shareFinished(const Response &response, const CommandContainer &commandContainer);
void onShareTimeout();
void onShareSelectionChanged(); void onShareSelectionChanged();
void handleConnectionChanged(ClientStatus status); void handleConnectionChanged(ClientStatus status);
@ -74,6 +76,7 @@ private:
ShareBarWidget *shareBar; ShareBarWidget *shareBar;
AbstractClient *client; AbstractClient *client;
QTimer *shareTimeoutTimer;
bool shareDeckAvailable = false; bool shareDeckAvailable = false;
}; };