diff options
| -rw-r--r-- | src/web_service/web_backend.cpp | 31 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_ui.cpp | 78 |
2 files changed, 26 insertions, 83 deletions
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index dff380cca..fdf3ac846 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp | |||
| @@ -32,9 +32,14 @@ struct Client::Impl { | |||
| 32 | Impl(std::string host_, std::string username_, std::string token_) | 32 | Impl(std::string host_, std::string username_, std::string token_) |
| 33 | : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} { | 33 | : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} { |
| 34 | std::scoped_lock lock{jwt_cache.mutex}; | 34 | std::scoped_lock lock{jwt_cache.mutex}; |
| 35 | if (username == jwt_cache.username && token == jwt_cache.token) { | 35 | if (this->username == jwt_cache.username && this->token == jwt_cache.token) { |
| 36 | jwt = jwt_cache.jwt; | 36 | jwt = jwt_cache.jwt; |
| 37 | } | 37 | } |
| 38 | |||
| 39 | // Normalize host expression | ||
| 40 | if (!this->host.empty() && this->host.back() == '/') { | ||
| 41 | static_cast<void>(this->host.pop_back()); | ||
| 42 | } | ||
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | /// A generic function handles POST, GET and DELETE request together | 45 | /// A generic function handles POST, GET and DELETE request together |
| @@ -71,18 +76,16 @@ struct Client::Impl { | |||
| 71 | const std::string& jwt_ = "", const std::string& username_ = "", | 76 | const std::string& jwt_ = "", const std::string& username_ = "", |
| 72 | const std::string& token_ = "") { | 77 | const std::string& token_ = "") { |
| 73 | if (cli == nullptr) { | 78 | if (cli == nullptr) { |
| 74 | cli = std::make_unique<httplib::Client>(host); | 79 | cli = std::make_unique<httplib::Client>(host.c_str()); |
| 80 | cli->set_connection_timeout(TIMEOUT_SECONDS); | ||
| 81 | cli->set_read_timeout(TIMEOUT_SECONDS); | ||
| 82 | cli->set_write_timeout(TIMEOUT_SECONDS); | ||
| 75 | } | 83 | } |
| 76 | |||
| 77 | if (!cli->is_valid()) { | 84 | if (!cli->is_valid()) { |
| 78 | LOG_ERROR(WebService, "Client is invalid, skipping request!"); | 85 | LOG_ERROR(WebService, "Invalid URL {}", host + path); |
| 79 | return {}; | 86 | return WebResult{WebResult::Code::InvalidURL, "Invalid URL", ""}; |
| 80 | } | 87 | } |
| 81 | 88 | ||
| 82 | cli->set_connection_timeout(TIMEOUT_SECONDS); | ||
| 83 | cli->set_read_timeout(TIMEOUT_SECONDS); | ||
| 84 | cli->set_write_timeout(TIMEOUT_SECONDS); | ||
| 85 | |||
| 86 | httplib::Headers params; | 89 | httplib::Headers params; |
| 87 | if (!jwt_.empty()) { | 90 | if (!jwt_.empty()) { |
| 88 | params = { | 91 | params = { |
| @@ -107,15 +110,15 @@ struct Client::Impl { | |||
| 107 | request.headers = params; | 110 | request.headers = params; |
| 108 | request.body = data; | 111 | request.body = data; |
| 109 | 112 | ||
| 110 | httplib::Response response; | 113 | httplib::Result result = cli->send(request); |
| 111 | httplib::Error error; | ||
| 112 | 114 | ||
| 113 | if (!cli->send(request, response, error)) { | 115 | if (!result) { |
| 114 | LOG_ERROR(WebService, "{} to {} returned null (httplib Error: {})", method, host + path, | 116 | LOG_ERROR(WebService, "{} to {} returned null", method, host + path); |
| 115 | httplib::to_string(error)); | ||
| 116 | return WebResult{WebResult::Code::LibError, "Null response", ""}; | 117 | return WebResult{WebResult::Code::LibError, "Null response", ""}; |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 120 | httplib::Response response = result.value(); | ||
| 121 | |||
| 119 | if (response.status >= 400) { | 122 | if (response.status >= 400) { |
| 120 | LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, | 123 | LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, |
| 121 | response.status); | 124 | response.status); |
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index c8e871151..f3c91586c 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp | |||
| @@ -248,82 +248,22 @@ void ConfigureUi::RetranslateUI() { | |||
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | void ConfigureUi::InitializeLanguageComboBox() { | 250 | void ConfigureUi::InitializeLanguageComboBox() { |
| 251 | // This is a list of lexicographically sorted languages, only the available translations are | ||
| 252 | // shown to the user. | ||
| 253 | static const struct { | ||
| 254 | const QString name; | ||
| 255 | const char* id; | ||
| 256 | } languages[] = { | ||
| 257 | // clang-format off | ||
| 258 | {QStringLiteral(u"Bahasa Indonesia"), "id"}, // Indonesian | ||
| 259 | {QStringLiteral(u"Bahasa Melayu"), "ms"}, // Malay | ||
| 260 | {QStringLiteral(u"Catal\u00E0"), "ca"}, // Catalan | ||
| 261 | {QStringLiteral(u"\u010Ce\u0161tina"), "cs"}, // Czech | ||
| 262 | {QStringLiteral(u"Dansk"), "da"}, // Danish | ||
| 263 | {QStringLiteral(u"Deutsch"), "de"}, // German | ||
| 264 | {QStringLiteral(u"English"), "en"}, // English | ||
| 265 | {QStringLiteral(u"Espa\u00F1ol"), "es"}, // Spanish | ||
| 266 | {QStringLiteral(u"Fran\u00E7ais"), "fr"}, // French | ||
| 267 | {QStringLiteral(u"Hrvatski"), "hr"}, // Croatian | ||
| 268 | {QStringLiteral(u"Italiano"), "it"}, // Italian | ||
| 269 | {QStringLiteral(u"Magyar"), "hu"}, // Hungarian | ||
| 270 | {QStringLiteral(u"Nederlands"), "nl"}, // Dutch | ||
| 271 | {QStringLiteral(u"Norsk bokm\u00E5l"), "nb"}, // Norwegian | ||
| 272 | {QStringLiteral(u"Polski"), "pl"}, // Polish | ||
| 273 | {QStringLiteral(u"Portugu\u00EAs"), "pt_PT"}, // Portuguese | ||
| 274 | {QStringLiteral(u"Portugu\u00EAs (Brasil)"), "pt_BR"}, // Portuguese (Brazil) | ||
| 275 | {QStringLiteral(u"Rom\u00E2n\u0103"), "ro"}, // Romanian | ||
| 276 | {QStringLiteral(u"Srpski"), "sr"}, // Serbian | ||
| 277 | {QStringLiteral(u"Suomi"), "fi"}, // Finnish | ||
| 278 | {QStringLiteral(u"Svenska"), "sv"}, // Swedish | ||
| 279 | {QStringLiteral(u"Ti\u1EBFng Vi\u1EC7t"), "vi"}, // Vietnamese | ||
| 280 | {QStringLiteral(u"Ti\u1EBFng Vi\u1EC7t (Vi\u1EC7t Nam)"), "vi_VN"}, // Vietnamese | ||
| 281 | {QStringLiteral(u"T\u00FCrk\u00E7e"), "tr_TR"}, // Turkish | ||
| 282 | {QStringLiteral(u"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"), "el"}, // Greek | ||
| 283 | {QStringLiteral(u"\u0420\u0443\u0441\u0441\u043A\u0438\u0439"), "ru_RU"}, // Russian | ||
| 284 | {QStringLiteral(u"\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"), | ||
| 285 | "uk"}, // Ukrainian | ||
| 286 | {QStringLiteral(u"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"), "ar"}, // Arabic | ||
| 287 | {QStringLiteral(u"\u0641\u0627\u0631\u0633\u06CC"), "fa"}, // Farsi | ||
| 288 | {QStringLiteral(u"\uD55C\uAD6D\uC5B4"), "ko_KR"}, // Korean | ||
| 289 | {QStringLiteral(u"\u65E5\u672C\u8A9E"), "ja_JP"}, // Japanese | ||
| 290 | {QStringLiteral(u"\u7B80\u4F53\u4E2D\u6587"), "zh_CN"}, // Simplified Chinese | ||
| 291 | {QStringLiteral(u"\u7E41\u9AD4\u4E2D\u6587"), "zh_TW"}, // Traditional Chinese | ||
| 292 | // clang-format on | ||
| 293 | }; | ||
| 294 | ui->language_combobox->addItem(tr("<System>"), QString{}); | 251 | ui->language_combobox->addItem(tr("<System>"), QString{}); |
| 295 | QDir languages_dir{QStringLiteral(":/languages")}; | 252 | ui->language_combobox->addItem(tr("English"), QStringLiteral("en")); |
| 296 | QStringList language_files = languages_dir.entryList(); | 253 | QDirIterator it(QStringLiteral(":/languages"), QDirIterator::NoIteratorFlags); |
| 297 | for (const auto& lang : languages) { | 254 | while (it.hasNext()) { |
| 298 | if (QString::fromLatin1(lang.id) == QStringLiteral("en")) { | 255 | QString locale = it.next(); |
| 299 | ui->language_combobox->addItem(lang.name, QStringLiteral("en")); | ||
| 300 | language_files.removeOne(QStringLiteral("en.qm")); | ||
| 301 | continue; | ||
| 302 | } | ||
| 303 | for (int i = 0; i < language_files.size(); ++i) { | ||
| 304 | QString locale = language_files[i]; | ||
| 305 | locale.truncate(locale.lastIndexOf(QLatin1Char{'.'})); | ||
| 306 | if (QString::fromLatin1(lang.id) == locale) { | ||
| 307 | ui->language_combobox->addItem(lang.name, locale); | ||
| 308 | language_files.removeAt(i); | ||
| 309 | break; | ||
| 310 | } | ||
| 311 | } | ||
| 312 | } | ||
| 313 | // Anything remaining will be at the bottom | ||
| 314 | for (const QString& file : language_files) { | ||
| 315 | LOG_CRITICAL(Frontend, "Unexpected Language File: {}", file.toStdString()); | ||
| 316 | QString locale = file; | ||
| 317 | locale.truncate(locale.lastIndexOf(QLatin1Char{'.'})); | 256 | locale.truncate(locale.lastIndexOf(QLatin1Char{'.'})); |
| 318 | const QString language_name = QLocale::languageToString(QLocale(locale).language()); | 257 | locale.remove(0, locale.lastIndexOf(QLatin1Char{'/'}) + 1); |
| 319 | const QString lang = QStringLiteral("%1 [%2]").arg(language_name, locale); | 258 | const QString lang = QLocale::languageToString(QLocale(locale).language()); |
| 320 | ui->language_combobox->addItem(lang, locale); | 259 | const QString country = QLocale::countryToString(QLocale(locale).country()); |
| 260 | ui->language_combobox->addItem(QStringLiteral("%1 (%2)").arg(lang, country), locale); | ||
| 321 | } | 261 | } |
| 322 | 262 | ||
| 323 | // Unlike other configuration changes, interface language changes need to be reflected on the | 263 | // Unlike other configuration changes, interface language changes need to be reflected on the |
| 324 | // interface immediately. This is done by passing a signal to the main window, and then | 264 | // interface immediately. This is done by passing a signal to the main window, and then |
| 325 | // retranslating when passing back. | 265 | // retranslating when passing back. |
| 326 | connect(ui->language_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, | 266 | connect(ui->language_combobox, qOverload<int>(&QComboBox::currentIndexChanged), this, |
| 327 | &ConfigureUi::OnLanguageChanged); | 267 | &ConfigureUi::OnLanguageChanged); |
| 328 | } | 268 | } |
| 329 | 269 | ||