mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:47:34 +00:00
Maps: Add show SerenityOS users feature
This commit is contained in:
parent
dfb54083ee
commit
d63fb8fa61
5 changed files with 138 additions and 3 deletions
BIN
Base/res/graphics/maps/marker-gray.png
Normal file
BIN
Base/res/graphics/maps/marker-gray.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 368 B |
|
@ -7,6 +7,7 @@ serenity_component(
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
main.cpp
|
main.cpp
|
||||||
MapWidget.cpp
|
MapWidget.cpp
|
||||||
|
UsersMapWidget.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
serenity_app(Maps ICON app-maps)
|
serenity_app(Maps ICON app-maps)
|
||||||
|
|
77
Userland/Applications/Maps/UsersMapWidget.cpp
Normal file
77
Userland/Applications/Maps/UsersMapWidget.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "UsersMapWidget.h"
|
||||||
|
#include <AK/JsonParser.h>
|
||||||
|
#include <LibDesktop/Launcher.h>
|
||||||
|
|
||||||
|
UsersMapWidget::UsersMapWidget(Options const& options)
|
||||||
|
: MapWidget::MapWidget(options)
|
||||||
|
{
|
||||||
|
m_marker_gray_image = Gfx::Bitmap::load_from_file("/res/graphics/maps/marker-gray.png"sv).release_value_but_fixme_should_propagate_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsersMapWidget::get_users()
|
||||||
|
{
|
||||||
|
// Start HTTP GET request to load people.json
|
||||||
|
HashMap<DeprecatedString, DeprecatedString> headers;
|
||||||
|
headers.set("User-Agent", "SerenityOS Maps");
|
||||||
|
headers.set("Accept", "application/json");
|
||||||
|
URL url("https://usermap.serenityos.org/people.json");
|
||||||
|
auto request = request_client()->start_request("GET", url, headers, {});
|
||||||
|
VERIFY(!request.is_null());
|
||||||
|
m_request = request;
|
||||||
|
request->on_buffered_request_finish = [this, request, url](bool success, auto, auto&, auto, ReadonlyBytes payload) {
|
||||||
|
m_request.clear();
|
||||||
|
if (!success) {
|
||||||
|
dbgln("Maps: Can't load: {}", url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse JSON data
|
||||||
|
JsonParser parser(payload);
|
||||||
|
auto result = parser.parse();
|
||||||
|
if (result.is_error()) {
|
||||||
|
dbgln("Maps: Can't parse JSON: {}", url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse each user
|
||||||
|
// FIXME: Handle JSON parsing errors
|
||||||
|
m_users = Vector<User>();
|
||||||
|
auto json_users = result.release_value().as_array();
|
||||||
|
for (size_t i = 0; i < json_users.size(); i++) {
|
||||||
|
auto const& json_user = json_users.at(i).as_object();
|
||||||
|
User user {
|
||||||
|
MUST(String::from_deprecated_string(json_user.get_deprecated_string("nick"sv).release_value())),
|
||||||
|
{ json_user.get_array("coordinates"sv).release_value().at(0).to_double(),
|
||||||
|
json_user.get_array("coordinates"sv).release_value().at(1).to_double() },
|
||||||
|
json_user.has_bool("contributor"sv),
|
||||||
|
};
|
||||||
|
m_users.value().append(user);
|
||||||
|
}
|
||||||
|
add_users_to_map();
|
||||||
|
};
|
||||||
|
request->set_should_buffer_all_input(true);
|
||||||
|
request->on_certificate_requested = []() -> Protocol::Request::CertificateAndKey { return {}; };
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsersMapWidget::add_users_to_map()
|
||||||
|
{
|
||||||
|
if (!m_users.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto const& user : m_users.value()) {
|
||||||
|
MapWidget::Marker marker = { user.coordinates, user.nick };
|
||||||
|
if (!user.contributor)
|
||||||
|
marker.image = m_marker_gray_image;
|
||||||
|
add_marker(marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_panel({ MUST(String::formatted("{} users are already registered", m_users.value().size())),
|
||||||
|
Panel::Position::TopRight,
|
||||||
|
{ { "https://github.com/SerenityOS/user-map" } } });
|
||||||
|
}
|
48
Userland/Applications/Maps/UsersMapWidget.h
Normal file
48
Userland/Applications/Maps/UsersMapWidget.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MapWidget.h"
|
||||||
|
|
||||||
|
class UsersMapWidget final : public MapWidget {
|
||||||
|
C_OBJECT(UsersMapWidget);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool show_users() const { return m_show_users; }
|
||||||
|
void set_show_users(bool show_users)
|
||||||
|
{
|
||||||
|
m_show_users = show_users;
|
||||||
|
if (m_show_users) {
|
||||||
|
if (!m_users.has_value()) {
|
||||||
|
get_users();
|
||||||
|
} else {
|
||||||
|
add_users_to_map();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clear_markers();
|
||||||
|
clear_panels();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
UsersMapWidget(Options const&);
|
||||||
|
|
||||||
|
void get_users();
|
||||||
|
|
||||||
|
void add_users_to_map();
|
||||||
|
|
||||||
|
RefPtr<Gfx::Bitmap> m_marker_gray_image;
|
||||||
|
RefPtr<Protocol::Request> m_request;
|
||||||
|
bool m_show_users { false };
|
||||||
|
|
||||||
|
struct User {
|
||||||
|
String nick;
|
||||||
|
LatLng coordinates;
|
||||||
|
bool contributor;
|
||||||
|
};
|
||||||
|
Optional<Vector<User>> m_users;
|
||||||
|
};
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MapWidget.h"
|
#include "UsersMapWidget.h"
|
||||||
#include <LibConfig/Client.h>
|
#include <LibConfig/Client.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
#include <LibGUI/Action.h>
|
#include <LibGUI/Action.h>
|
||||||
|
@ -45,18 +45,22 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
auto toolbar = TRY(toolbar_container->try_add<GUI::Toolbar>());
|
auto toolbar = TRY(toolbar_container->try_add<GUI::Toolbar>());
|
||||||
|
|
||||||
// Map widget
|
// Map widget
|
||||||
MapWidget::Options options {};
|
UsersMapWidget::Options options {};
|
||||||
options.center.latitude = Config::read_string("Maps"sv, "MapView"sv, "CenterLatitude"sv, "30"sv).to_double().value_or(30.0);
|
options.center.latitude = Config::read_string("Maps"sv, "MapView"sv, "CenterLatitude"sv, "30"sv).to_double().value_or(30.0);
|
||||||
options.center.longitude = Config::read_string("Maps"sv, "MapView"sv, "CenterLongitude"sv, "0"sv).to_double().value_or(0.0);
|
options.center.longitude = Config::read_string("Maps"sv, "MapView"sv, "CenterLongitude"sv, "0"sv).to_double().value_or(0.0);
|
||||||
options.zoom = Config::read_i32("Maps"sv, "MapView"sv, "Zoom"sv, MAP_ZOOM_DEFAULT);
|
options.zoom = Config::read_i32("Maps"sv, "MapView"sv, "Zoom"sv, MAP_ZOOM_DEFAULT);
|
||||||
auto maps = TRY(root_widget->try_add<MapWidget>(options));
|
auto maps = TRY(root_widget->try_add<UsersMapWidget>(options));
|
||||||
maps->set_frame_style(Gfx::FrameStyle::SunkenContainer);
|
maps->set_frame_style(Gfx::FrameStyle::SunkenContainer);
|
||||||
|
maps->set_show_users(Config::read_bool("Maps"sv, "MapView"sv, "ShowUsers"sv, false));
|
||||||
|
|
||||||
// Main menu actions
|
// Main menu actions
|
||||||
auto file_menu = window->add_menu("&File"_string);
|
auto file_menu = window->add_menu("&File"_string);
|
||||||
file_menu->add_action(GUI::CommonActions::make_quit_action([](auto&) { GUI::Application::the()->quit(); }));
|
file_menu->add_action(GUI::CommonActions::make_quit_action([](auto&) { GUI::Application::the()->quit(); }));
|
||||||
|
|
||||||
auto view_menu = window->add_menu("&View"_string);
|
auto view_menu = window->add_menu("&View"_string);
|
||||||
|
auto show_users_action = GUI::Action::create_checkable(
|
||||||
|
"Show SerenityOS users", TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/ladyball.png"sv)), [maps](auto& action) { maps->set_show_users(action.is_checked()); }, window);
|
||||||
|
show_users_action->set_checked(maps->show_users());
|
||||||
auto zoom_in_action = GUI::CommonActions::make_zoom_in_action([maps](auto&) { maps->set_zoom(maps->zoom() + 1); }, window);
|
auto zoom_in_action = GUI::CommonActions::make_zoom_in_action([maps](auto&) { maps->set_zoom(maps->zoom() + 1); }, window);
|
||||||
auto zoom_out_action = GUI::CommonActions::make_zoom_out_action([maps](auto&) { maps->set_zoom(maps->zoom() - 1); }, window);
|
auto zoom_out_action = GUI::CommonActions::make_zoom_out_action([maps](auto&) { maps->set_zoom(maps->zoom() - 1); }, window);
|
||||||
auto reset_zoom_action = GUI::CommonActions::make_reset_zoom_action([maps](auto&) { maps->set_zoom(MAP_ZOOM_DEFAULT); }, window);
|
auto reset_zoom_action = GUI::CommonActions::make_reset_zoom_action([maps](auto&) { maps->set_zoom(MAP_ZOOM_DEFAULT); }, window);
|
||||||
|
@ -66,6 +70,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
maps->set_frame_style(window->is_fullscreen() ? Gfx::FrameStyle::NoFrame : Gfx::FrameStyle::SunkenContainer);
|
maps->set_frame_style(window->is_fullscreen() ? Gfx::FrameStyle::NoFrame : Gfx::FrameStyle::SunkenContainer);
|
||||||
},
|
},
|
||||||
window);
|
window);
|
||||||
|
view_menu->add_action(show_users_action);
|
||||||
|
view_menu->add_separator();
|
||||||
view_menu->add_action(zoom_in_action);
|
view_menu->add_action(zoom_in_action);
|
||||||
view_menu->add_action(zoom_out_action);
|
view_menu->add_action(zoom_out_action);
|
||||||
view_menu->add_action(reset_zoom_action);
|
view_menu->add_action(reset_zoom_action);
|
||||||
|
@ -77,6 +83,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
help_menu->add_action(GUI::CommonActions::make_about_action("Maps", app_icon, window));
|
help_menu->add_action(GUI::CommonActions::make_about_action("Maps", app_icon, window));
|
||||||
|
|
||||||
// Main toolbar actions
|
// Main toolbar actions
|
||||||
|
toolbar->add_action(show_users_action);
|
||||||
|
toolbar->add_separator();
|
||||||
toolbar->add_action(zoom_in_action);
|
toolbar->add_action(zoom_in_action);
|
||||||
toolbar->add_action(zoom_out_action);
|
toolbar->add_action(zoom_out_action);
|
||||||
toolbar->add_action(reset_zoom_action);
|
toolbar->add_action(reset_zoom_action);
|
||||||
|
@ -88,5 +96,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
Config::write_string("Maps"sv, "MapView"sv, "CenterLatitude"sv, TRY(String::number(maps->center().latitude)));
|
Config::write_string("Maps"sv, "MapView"sv, "CenterLatitude"sv, TRY(String::number(maps->center().latitude)));
|
||||||
Config::write_string("Maps"sv, "MapView"sv, "CenterLongitude"sv, TRY(String::number(maps->center().longitude)));
|
Config::write_string("Maps"sv, "MapView"sv, "CenterLongitude"sv, TRY(String::number(maps->center().longitude)));
|
||||||
Config::write_i32("Maps"sv, "MapView"sv, "Zoom"sv, maps->zoom());
|
Config::write_i32("Maps"sv, "MapView"sv, "Zoom"sv, maps->zoom());
|
||||||
|
Config::write_bool("Maps"sv, "MapView"sv, "ShowUsers"sv, maps->show_users());
|
||||||
return exec;
|
return exec;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue