diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 6fd683461..9ea463eef 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -246,6 +246,7 @@ set(cockatrice_SOURCES src/interface/widgets/replay/replay_widget.cpp src/interface/widgets/server/chat_view/chat_view.cpp src/interface/widgets/server/game_filter_configs.cpp + src/interface/widgets/server/game_link.cpp src/interface/widgets/server/game_selector.cpp src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp src/interface/widgets/server/games_model.cpp diff --git a/cockatrice/src/interface/widgets/server/game_link.cpp b/cockatrice/src/interface/widgets/server/game_link.cpp new file mode 100644 index 000000000..c866f6571 --- /dev/null +++ b/cockatrice/src/interface/widgets/server/game_link.cpp @@ -0,0 +1,23 @@ +#include "game_link.h" + +#include +#include + +QString makeGameJoinLink(const QString &hostname, int port, int roomId, int gameId, const QString &description) +{ + QUrl url; + url.setScheme("cockatrice"); + url.setHost("joingame"); + QUrlQuery query; + query.addQueryItem("hostname", hostname); + query.addQueryItem("port", QString::number(port)); + query.addQueryItem("roomid", QString::number(roomId)); + query.addQueryItem("gameid", QString::number(gameId)); + if (!description.isEmpty()) { + // addQueryItem percent-encodes, so arbitrary descriptions (quotes, + // ampersands, non-ASCII…) survive the trip through chat. + query.addQueryItem("game", description); + } + url.setQuery(query); + return url.toString(QUrl::FullyEncoded); +} diff --git a/cockatrice/src/interface/widgets/server/game_link.h b/cockatrice/src/interface/widgets/server/game_link.h new file mode 100644 index 000000000..d57bbd6d2 --- /dev/null +++ b/cockatrice/src/interface/widgets/server/game_link.h @@ -0,0 +1,41 @@ +/** + * @file game_link.h + * @ingroup UI + * @brief Builds cockatrice://joingame links that let another user join a server game. + */ + +#ifndef GAME_LINK_H +#define GAME_LINK_H + +#include + +/** + * Builds a cockatrice://joingame link for the given server game. The receiver's + * client opens it through the intent chain (connect -> join room -> join game). + * @p description, when non-empty, is embedded in the link as the URL-encoded + * "game" query item so the receiving client can name the game in its confirm + * prompt and chat anchor instead of only its numeric id. Links built without it + * stay valid: the parser and chat renderer fall back to the id alone. + */ +QString +makeGameJoinLink(const QString &hostname, int port, int roomId, int gameId, const QString &description = QString()); + +/** + * One game the inviter is currently in and can invite another user to. + * @p label is meant for display in menus, @p url is the ready-made invite link. + * @p description is the raw game description for building tr()-wrapped invite + * messages (the label already embeds it, but the send sites need the raw value). + * @p onlyBuddies and @p creatorName mirror the server game's room settings so + * callers can gate the invite to the creator's buddies. + */ +struct GameInviteOption +{ + int gameId = 0; + QString label; + QString url; + QString description; + bool onlyBuddies = false; + QString creatorName; +}; + +#endif // GAME_LINK_H diff --git a/cockatrice/src/interface/widgets/server/game_selector.cpp b/cockatrice/src/interface/widgets/server/game_selector.cpp index 6580f0262..a1a2fb577 100644 --- a/cockatrice/src/interface/widgets/server/game_selector.cpp +++ b/cockatrice/src/interface/widgets/server/game_selector.cpp @@ -7,6 +7,7 @@ #include "../interface/widgets/tabs/tab_room.h" #include "../interface/widgets/tabs/tab_supervisor.h" #include "../interface/widgets/utility/get_text_with_max.h" +#include "game_link.h" #include "games_model.h" #include "user/user_list_manager.h" @@ -18,8 +19,6 @@ #include #include #include -#include -#include #include #include #include @@ -323,16 +322,9 @@ void GameSelector::customContextMenu(const QPoint &point) QAction copyLink(tr("Copy Game Link")); connect(©Link, &QAction::triggered, this, [=, this]() { const ServerInfo_Game &gameInfo = gameListModel->getGame(index.data(Qt::UserRole).toInt()); - QUrl url; - url.setScheme("cockatrice"); - url.setHost("joingame"); - QUrlQuery query; - query.addQueryItem("hostname", client->serverName()); - query.addQueryItem("port", QString::number(client->serverPort())); - query.addQueryItem("roomid", QString::number(gameInfo.room_id())); - query.addQueryItem("gameid", QString::number(gameInfo.game_id())); - url.setQuery(query); - QGuiApplication::clipboard()->setText(url.toString(QUrl::FullyEncoded)); + QGuiApplication::clipboard()->setText(makeGameJoinLink(client->serverName(), client->serverPort(), + gameInfo.room_id(), gameInfo.game_id(), + QString::fromStdString(gameInfo.description()))); }); QMenu menu;