UsersMapWidget.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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->set_buffered_request_finished_callback([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->on_certificate_requested = []() -> Protocol::Request::CertificateAndKey { return {}; };
  56. }
  57. void UsersMapWidget::add_users_to_map()
  58. {
  59. if (!m_users.has_value())
  60. return;
  61. for (auto const& user : m_users.value()) {
  62. MapWidget::Marker marker = { user.coordinates, user.nick, {}, "users"_string };
  63. if (!user.contributor)
  64. marker.image = m_marker_gray_image;
  65. add_marker(marker);
  66. }
  67. add_panel({ MUST(String::formatted("{} users are already registered", m_users.value().size())),
  68. Panel::Position::TopRight,
  69. { { "https://github.com/SerenityOS/user-map" } },
  70. "users"_string });
  71. }
  72. }