UsersMapWidget.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "UsersMapWidget.h"
  7. #include <AK/JsonParser.h>
  8. #include <LibDesktop/Launcher.h>
  9. namespace Maps {
  10. UsersMapWidget::UsersMapWidget(Options const& options)
  11. : MapWidget::MapWidget(options)
  12. {
  13. m_marker_gray_image = Gfx::Bitmap::load_from_file("/res/graphics/maps/marker-gray.png"sv).release_value_but_fixme_should_propagate_errors();
  14. }
  15. void UsersMapWidget::get_users()
  16. {
  17. // Start HTTP GET request to load people.json
  18. HashMap<ByteString, ByteString> headers;
  19. headers.set("User-Agent", "SerenityOS Maps");
  20. headers.set("Accept", "application/json");
  21. URL::URL url("https://usermap.serenityos.org/people.json");
  22. auto request = request_client()->start_request("GET", url, headers, {});
  23. VERIFY(!request.is_null());
  24. m_request = request;
  25. request->on_buffered_request_finish = [this, request, url](bool success, auto, auto&, auto, ReadonlyBytes payload) {
  26. m_request.clear();
  27. if (!success) {
  28. dbgln("Maps: Can't load: {}", url);
  29. return;
  30. }
  31. // Parse JSON data
  32. JsonParser parser(payload);
  33. auto result = parser.parse();
  34. if (result.is_error()) {
  35. dbgln("Maps: Can't parse JSON: {}", url);
  36. return;
  37. }
  38. // Parse each user
  39. // FIXME: Handle JSON parsing errors
  40. m_users = Vector<User>();
  41. auto json_users = result.release_value().as_array();
  42. for (size_t i = 0; i < json_users.size(); i++) {
  43. auto const& json_user = json_users.at(i).as_object();
  44. auto const& coordinates = json_user.get_array("coordinates"sv).release_value();
  45. User user {
  46. MUST(String::from_byte_string(json_user.get_byte_string("nick"sv).release_value())),
  47. { coordinates[0].get_double_with_precision_loss().value(),
  48. coordinates[1].get_double_with_precision_loss().value() },
  49. json_user.has_bool("contributor"sv),
  50. };
  51. m_users.value().append(user);
  52. }
  53. add_users_to_map();
  54. };
  55. request->set_should_buffer_all_input(true);
  56. request->on_certificate_requested = []() -> Protocol::Request::CertificateAndKey { return {}; };
  57. }
  58. void UsersMapWidget::add_users_to_map()
  59. {
  60. if (!m_users.has_value())
  61. return;
  62. for (auto const& user : m_users.value()) {
  63. MapWidget::Marker marker = { user.coordinates, user.nick, {}, "users"_string };
  64. if (!user.contributor)
  65. marker.image = m_marker_gray_image;
  66. add_marker(marker);
  67. }
  68. add_panel({ MUST(String::formatted("{} users are already registered", m_users.value().size())),
  69. Panel::Position::TopRight,
  70. { { "https://github.com/SerenityOS/user-map" } },
  71. "users"_string });
  72. }
  73. }