32 using namespace std::chrono_literals;
35 #define DBG_NW LOG_STREAM(debug, log_network)
36 #define ERR_NW LOG_STREAM(err, log_network)
44 , player_name_(player_name)
45 , connection_(connection)
47 , wait_for_response_(wait_for_response)
49 register_label(
"title",
true,
VGETTEXT(
"Match History — $player", {{
"player", player_name_}}));
52 void mp_match_history::pre_show()
54 set_enter_disabled(
true);
56 button& newer_history = find_widget<button>(
"newer_history");
57 button& older_history = find_widget<button>(
"older_history");
61 button& search = find_widget<button>(
"search");
64 text_box& search_player = find_widget<text_box>(
"search_player");
67 std::vector<config> content_types;
68 content_types.emplace_back(
"label",
_(
"Scenario"));
69 content_types.emplace_back(
"label",
_(
"Era"));
70 content_types.emplace_back(
"label",
_(
"Modification"));
72 find_widget<menu_button>(
"search_content_type").set_values(content_types);
77 void mp_match_history::new_search()
79 int old_offset = offset_;
80 std::string old_player_name = player_name_;
81 text_box& search_player = find_widget<text_box>(
"search_player");
85 if(!update_display()) {
87 player_name_ = old_player_name;
89 label& title = find_widget<label>(
"title");
94 void mp_match_history::newer_history_offset()
98 if(!update_display()) {
103 void mp_match_history::older_history_offset()
107 if(!update_display()) {
119 if(std::string
s = val.
str(); !
s.empty()) {
127 bool mp_match_history::update_display()
129 const config history = request_history();
132 if(history.
child_count(
"game_history_results") == 0) {
136 listbox* history_box = find_widget<listbox>(
"history",
false,
true);
137 history_box->
clear();
139 listbox* tab_bar = find_widget<listbox>(
"tab_bar",
false,
true);
148 dynamic_cast<label*
>(history_grid.
find(
"game_name",
false))->set_label(key_with_fallback(
game[
"game_name"]));
149 dynamic_cast<label*
>(history_grid.
find(
"scenario_name",
false))->set_label(key_with_fallback(
game[
"scenario_name"]));
151 dynamic_cast<label*
>(history_grid.
find(
"game_start",
false))->set_label(key_with_fallback(
game[
"game_start"]) +
_(
" UTC+0"));
152 dynamic_cast<label*
>(history_grid.
find(
"version",
false))->set_label(key_with_fallback(
game[
"version"]));
154 button* replay_download =
dynamic_cast<button*
>(history_grid.
find(
"replay_download",
false));
155 std::string replay_url =
game[
"replay_url"].str();
156 if(!replay_url.empty()) {
165 std::vector<std::string> player_list;
166 std::vector<std::string> player_faction_list;
167 for(
const config& player :
game.child_range(
"player")) {
169 player_faction_list.emplace_back(player[
"faction"].str());
172 label* players =
dynamic_cast<label*
>(history_grid.
find(
"players",
false));
175 label* factions =
dynamic_cast<label*
>(history_grid.
find(
"player_factions",
false));
180 label* modifications =
dynamic_cast<label*
>(history_grid.
find(
"modifications",
false));
181 const auto& children =
game.child_range(
"modification");
182 if(!children.empty()) {
183 std::vector<std::string> modifications_list;
185 for(
const config& modification :
game.child_range(
"modification")) {
201 button* newer_history = find_widget<button>(
"newer_history",
false,
true);
204 button* newer_history = find_widget<button>(
"newer_history",
false,
true);
210 if(history.
child_count(
"game_history_result") < 11) {
211 button* older_history = find_widget<button>(
"older_history",
false,
true);
214 button* older_history = find_widget<button>(
"older_history",
false,
true);
221 const config mp_match_history::request_history()
225 child[
"offset"] = offset_;
226 child[
"search_player"] = player_name_;
227 child[
"search_game_name"] = find_widget<text_box>(
"search_game_name").get_value();
228 child[
"search_content_type"] = find_widget<menu_button>(
"search_content_type").get_value();
229 child[
"search_content"] = find_widget<text_box>(
"search_content").get_value();
231 connection_.send_data(request);
233 int times_waited = 0;
243 if(connection_.receive_data(response)) {
244 if(response.
child_count(
"game_history_results") == 0) {
245 DBG_NW <<
"Received non-history data: " << response.
debug();
246 if(!response[
"error"].str().empty()) {
247 ERR_NW <<
"Received error from server: " << response[
"error"].str();
252 DBG_NW <<
"Player has no game history data.";
256 DBG_NW <<
"Received history data: " << response.
debug();
260 DBG_NW <<
"Received no data";
263 if(times_waited > 20 || !wait_for_response_) {
264 ERR_NW <<
"Timed out waiting for history data, returning nothing";
265 if(wait_for_response_) {
272 std::this_thread::sleep_for(250ms);
275 DBG_NW <<
"Something else happened while waiting for history data, returning nothing";
280 void mp_match_history::tab_switch_callback()
282 listbox* history_box = find_widget<listbox>(
"history",
false,
true);
283 listbox* tab_bar = find_widget<listbox>(
"tab_bar",
false,
true);
291 }
else if(tab == 1) {
294 }
else if(tab == 2) {
Variant for storing WML attributes.
std::string str(const std::string &fallback="") const
A config object defines a single node in a WML file, with access to child nodes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
std::size_t child_count(config_key_type key) const
child_itors child_range(config_key_type key)
std::string debug() const
config & add_child(config_key_type key)
Abstract base class for all modal dialogs.
widget * find(const std::string_view id, const bool must_be_active) override
See widget::find.
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
const grid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
bool select_row(const unsigned row, const bool select=true)
Selects a row.
void clear()
Removes all the rows in the listbox, clearing it.
int get_selected_row() const
Returns the first selected row.
unsigned get_item_count() const
Returns the number of items in the listbox.
std::string get_value() const
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
A widget that allows the user to input text in single line.
A class that represents a TCP/IP connection to the wesnothd server.
Declarations for File-IO.
static std::string _(const char *str)
static lg::log_domain log_network("network")
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
std::string get_saves_dir()
const std::string unicode_em_dash
const std::string unicode_bullet
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
std::map< std::string, widget_item > widget_data
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
std::string span_color(const color_t &color, Args &&... data)
void download(const std::string &url, const std::string &local_path)
Initiates a standalone download of a single file from an HTTPS URL.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::vector< std::string > split(const config_attribute_value &val)
std::string filename
Filename.
static map_location::direction s