diff --git a/modules/ui_shared/include/ui/screens/team/team_page_event_effect_sink.h b/modules/ui_shared/include/ui/screens/team/team_page_event_effect_sink.h index 30b7e4ee..d3bc9521 100644 --- a/modules/ui_shared/include/ui/screens/team/team_page_event_effect_sink.h +++ b/modules/ui_shared/include/ui/screens/team/team_page_event_effect_sink.h @@ -55,8 +55,7 @@ class TeamPageEventEffectSink const TeamPageRuntimePort& runtime, const TeamPageKeyEventLog& key_log, ITeamPageEventDeferred& deferred, - ITeamPageEventNotifier& notifier, - const ITeamPageMemberNameResolver& names) const; + ITeamPageEventNotifier& notifier) const; }; } // namespace ui diff --git a/modules/ui_shared/include/ui/screens/team/team_page_event_reducer.h b/modules/ui_shared/include/ui/screens/team/team_page_event_reducer.h index 99b4bf2d..5a6357a8 100644 --- a/modules/ui_shared/include/ui/screens/team/team_page_event_reducer.h +++ b/modules/ui_shared/include/ui/screens/team/team_page_event_reducer.h @@ -36,18 +36,10 @@ struct TeamPageEventState std::vector members; }; -class ITeamPageMemberNameResolver -{ - public: - virtual ~ITeamPageMemberNameResolver() = default; - virtual std::string resolveMemberName(uint32_t node_id) const = 0; -}; - struct TeamPageEventContext { uint32_t now_s = 0; uint32_t self_node_id = 0; - const ITeamPageMemberNameResolver* names = nullptr; }; struct TeamPageEventEffects @@ -143,7 +135,7 @@ class TeamPageEventReducer void applyPairingIdentity(TeamPageEventState& state, const TeamPagePairingUpdate& update) const; bool isPairingActive(TeamPairingState state) const; - std::string resolveMemberName(uint32_t node_id) const; + std::string memberDisplayLabel(uint32_t node_id) const; void assignMemberColor(TeamMemberUi& member) const; TeamPageEventContext context_; diff --git a/modules/ui_shared/include/ui/team_presentation/team_member_label.h b/modules/ui_shared/include/ui/team_presentation/team_member_label.h new file mode 100644 index 00000000..bf147a2f --- /dev/null +++ b/modules/ui_shared/include/ui/team_presentation/team_member_label.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +namespace ui +{ +namespace team_presentation +{ + +inline std::string shortTeamMemberLabel(uint32_t node_id) +{ + char label[5]{}; + std::snprintf(label, + sizeof(label), + "%04lX", + static_cast(node_id & 0xFFFFU)); + return std::string(label); +} + +} // namespace team_presentation +} // namespace ui diff --git a/modules/ui_shared/src/ui/presentation_sources/team_map_overlay_source.cpp b/modules/ui_shared/src/ui/presentation_sources/team_map_overlay_source.cpp index 939e2a6c..714deefa 100644 --- a/modules/ui_shared/src/ui/presentation_sources/team_map_overlay_source.cpp +++ b/modules/ui_shared/src/ui/presentation_sources/team_map_overlay_source.cpp @@ -1,6 +1,9 @@ #include "ui/presentation_sources/team_map_overlay_source.h" +#include "ui/team_presentation/team_member_label.h" + #include +#include #include namespace ui::presentation_sources @@ -184,12 +187,14 @@ const char* TeamMapOverlaySource::labelForMember( for (const auto& member : snapshot.members) { - if (member.node_id == member_id && !member.name.empty()) + if (member.node_id == member_id) { + const std::string label = + ::ui::team_presentation::shortTeamMemberLabel(member_id); std::snprintf(labels[index], sizeof(labels[index]), "%s", - member.name.c_str()); + label.c_str()); return labels[index]; } } diff --git a/modules/ui_shared/src/ui/screens/gps/gps_page_runtime.cpp b/modules/ui_shared/src/ui/screens/gps/gps_page_runtime.cpp index d2a9c079..cdf4b3e2 100644 --- a/modules/ui_shared/src/ui/screens/gps/gps_page_runtime.cpp +++ b/modules/ui_shared/src/ui/screens/gps/gps_page_runtime.cpp @@ -6,7 +6,6 @@ using Projection = gps::ui::shell::Projection; #include "app/app_config.h" #include "app/app_facade_access.h" -#include "chat/usecase/contact_service.h" #include "gps/domain/gps_diagnostics.h" #include "platform/ui/device_runtime.h" #include "platform/ui/gps_runtime.h" @@ -21,6 +20,7 @@ using Projection = gps::ui::shell::Projection; #include "ui/presentation_sources/team_map_overlay_source.h" #include "ui/screens/gps/gps_constants.h" #include "ui/support/lvgl_fs_utils.h" +#include "ui/team_presentation/team_member_label.h" #include "ui/ui_common.h" #include "ui/widgets/map/map_viewport.h" #include "ui/widgets/system_notification.h" @@ -519,23 +519,12 @@ uint32_t member_color(const ::team::ui::TeamMemberUi& member) std::string member_label(const ::team::ui::TeamMemberUi& member) { - const uint32_t member_id = member_id_for_button(member); - std::string contact_name = app::messagingFacade().getContactService().getContactName(member_id); - if (!contact_name.empty()) + if (member.node_id == 0) { - return contact_name; + return member.name.empty() ? std::string("You") : member.name; } - if (!member.name.empty()) - { - return member.name; - } - - char fallback[8]{}; - std::snprintf(fallback, - sizeof(fallback), - "%04lX", - static_cast(member_id & 0xFFFFU)); - return fallback; + return ::ui::team_presentation::shortTeamMemberLabel( + member_id_for_button(member)); } uint32_t hash_member_list(const ::team::ui::TeamUiSnapshot& snapshot) diff --git a/modules/ui_shared/src/ui/screens/team/team_page_components.cpp b/modules/ui_shared/src/ui/screens/team/team_page_components.cpp index c1a697c5..0fe0e470 100644 --- a/modules/ui_shared/src/ui/screens/team/team_page_components.cpp +++ b/modules/ui_shared/src/ui/screens/team/team_page_components.cpp @@ -5,7 +5,6 @@ #include "ui/screens/team/team_page_components.h" #include "app/app_facade_access.h" -#include "chat/usecase/contact_service.h" #include "platform/ui/team_ui_store_runtime.h" #include "sys/clock.h" #include "sys/event_bus.h" @@ -37,6 +36,7 @@ #include "ui/screens/team/team_page_state_store.h" #include "ui/screens/team/team_page_styles.h" #include "ui/screens/team/team_page_transfer_leader_action.h" +#include "ui/team_presentation/team_member_label.h" #include "ui/ui_common.h" #include "ui/widgets/system_notification.h" #include "ui/widgets/top_bar.h" @@ -177,7 +177,7 @@ uint8_t next_random_byte() uint32_t now_secs(); bool is_team_ui_active(); bool is_team_chat_visible(); -std::string resolve_node_name(uint32_t node_id); +std::string resolve_node_label(uint32_t node_id); bool is_pairing_active(); void sync_pairing_from_service(); void fill_status_members(team::proto::TeamStatus& status); @@ -379,17 +379,12 @@ void apply_pairing_command_failures( } } -class TeamPageMemberNameResolver final : public ITeamPageMemberNameResolver, public ITeamPageLvglNameResolver +class TeamPageNodeLabelResolver final : public ITeamPageLvglNameResolver { public: - std::string resolveMemberName(uint32_t node_id) const override - { - return resolve_node_name(node_id); - } - std::string resolveNodeName(uint32_t node_id) const override { - return resolve_node_name(node_id); + return resolve_node_label(node_id); } }; @@ -468,11 +463,9 @@ TeamPageFlowController current_flow_controller() TeamPageEventReducer current_event_reducer() { - static TeamPageMemberNameResolver names; TeamPageEventContext context; context.now_s = now_secs(); context.self_node_id = app::messagingFacade().getSelfNodeId(); - context.names = &names; return TeamPageEventReducer(context); } @@ -548,7 +541,6 @@ class TeamPageEventNotifierAdapter final : public ITeamPageEventNotifier TeamPageEventEffectResult apply_event_effects( const TeamPageEventEffects& effects) { - static TeamPageMemberNameResolver names; static TeamPageEventDeferredAdapter deferred; static TeamPageEventNotifierAdapter notifier; auto key_state = key_event_state_from_page(); @@ -560,8 +552,7 @@ TeamPageEventEffectResult apply_event_effects( current_runtime_port(), current_key_event_log(), deferred, - notifier, - names); + notifier); apply_key_event_state_to_page(key_state); apply_event_navigation_requests(result); return result; @@ -1023,16 +1014,9 @@ TeamPageReadModel current_read_model() return TeamPageReadModel(now_secs()); } -std::string resolve_node_name(uint32_t node_id) +std::string resolve_node_label(uint32_t node_id) { - std::string name = app::messagingFacade().getContactService().getContactName(node_id); - if (!name.empty()) - { - return name; - } - char fallback[16]; - snprintf(fallback, sizeof(fallback), "%08lX", static_cast(node_id)); - return std::string(fallback); + return ::ui::team_presentation::shortTeamMemberLabel(node_id); } TeamPageColorContext current_color_context() @@ -1738,7 +1722,7 @@ void render_page() input.read_model = read_model_input; input.pairing_peer_id = team_page_state().pairing_peer_id; - static TeamPageMemberNameResolver names; + static TeamPageNodeLabelResolver names; TeamPageLvglRenderer(now_secs()).render(context, input, handlers, names); ui_update_top_bar_battery(team_page_lvgl_context().top_bar_widget); diff --git a/modules/ui_shared/src/ui/screens/team/team_page_event_effect_sink.cpp b/modules/ui_shared/src/ui/screens/team/team_page_event_effect_sink.cpp index 74fff08d..25e200e1 100644 --- a/modules/ui_shared/src/ui/screens/team/team_page_event_effect_sink.cpp +++ b/modules/ui_shared/src/ui/screens/team/team_page_event_effect_sink.cpp @@ -1,6 +1,7 @@ #include "ui/screens/team/team_page_event_effect_sink.h" #include "chat/domain/chat_types.h" +#include "ui/team_presentation/team_member_label.h" namespace team { @@ -21,8 +22,7 @@ TeamPageEventEffectResult TeamPageEventEffectSink::applyEffects( const TeamPageRuntimePort& runtime, const TeamPageKeyEventLog& key_log, ITeamPageEventDeferred& deferred, - ITeamPageEventNotifier& notifier, - const ITeamPageMemberNameResolver& names) const + ITeamPageEventNotifier& notifier) const { TeamPageEventEffectResult result; result.request_status_in_team_page = @@ -98,7 +98,8 @@ TeamPageEventEffectResult TeamPageEventEffectSink::applyEffects( if (effects.show_pairing_peer) { const std::string name = - names.resolveMemberName(effects.pairing_peer_id); + ::ui::team_presentation::shortTeamMemberLabel( + effects.pairing_peer_id); const std::string message = "Paired: " + name; notifier.showMessage(message.c_str()); } diff --git a/modules/ui_shared/src/ui/screens/team/team_page_event_reducer.cpp b/modules/ui_shared/src/ui/screens/team/team_page_event_reducer.cpp index 01f487f9..d943ce26 100644 --- a/modules/ui_shared/src/ui/screens/team/team_page_event_reducer.cpp +++ b/modules/ui_shared/src/ui/screens/team/team_page_event_reducer.cpp @@ -1,9 +1,9 @@ #include "ui/screens/team/team_page_event_reducer.h" #include "ui/team_presence/team_presence_model.h" +#include "ui/team_presentation/team_member_label.h" #include -#include namespace team { @@ -44,7 +44,7 @@ void TeamPageEventReducer::touchMember(TeamPageEventState& state, } auto& member = state.members[result.index]; - member.name = resolveMemberName(node_id); + member.name = memberDisplayLabel(node_id); assignMemberColor(member); } @@ -120,7 +120,7 @@ void TeamPageEventReducer::applyStatusRoster( entry.leader = (id == status.leader_id); if (entry.name.empty()) { - entry.name = (node_id == 0) ? "You" : resolveMemberName(id); + entry.name = (node_id == 0) ? "You" : memberDisplayLabel(id); } if (node_id == 0 && entry.last_seen_s == 0) { @@ -309,7 +309,7 @@ TeamPageEventEffects TeamPageEventReducer::reduceTransferLeader( { TeamMemberUi info; info.node_id = target; - info.name = resolveMemberName(target); + info.name = memberDisplayLabel(target); info.leader = true; info.last_seen_s = context_.now_s; assignMemberColor(info); @@ -380,7 +380,7 @@ TeamPageEventEffects TeamPageEventReducer::reduceKeyDist( { TeamMemberUi leader; leader.node_id = leader_id; - leader.name = resolveMemberName(leader_id); + leader.name = memberDisplayLabel(leader_id); leader.leader = true; leader.last_seen_s = context_.now_s; assignMemberColor(leader); @@ -600,27 +600,13 @@ bool TeamPageEventReducer::isPairingActive(TeamPairingState state) const state != TeamPairingState::Failed; } -std::string TeamPageEventReducer::resolveMemberName(uint32_t node_id) const +std::string TeamPageEventReducer::memberDisplayLabel(uint32_t node_id) const { if (node_id == 0) { return "You"; } - if (context_.names) - { - std::string name = context_.names->resolveMemberName(node_id); - if (!name.empty()) - { - return name; - } - } - - char fallback[16]; - std::snprintf(fallback, - sizeof(fallback), - "%08lX", - static_cast(node_id)); - return std::string(fallback); + return ::ui::team_presentation::shortTeamMemberLabel(node_id); } void TeamPageEventReducer::assignMemberColor(TeamMemberUi& member) const diff --git a/modules/ui_shared/src/ui/screens/team/team_page_read_model.cpp b/modules/ui_shared/src/ui/screens/team/team_page_read_model.cpp index 2afb9627..ee0abef2 100644 --- a/modules/ui_shared/src/ui/screens/team/team_page_read_model.cpp +++ b/modules/ui_shared/src/ui/screens/team/team_page_read_model.cpp @@ -2,6 +2,7 @@ #include "platform/ui/team_ui_snapshot_store.h" #include "ui/team_presence/team_presence_model.h" +#include "ui/team_presentation/team_member_label.h" #include @@ -203,7 +204,9 @@ TeamMemberRowView TeamPageReadModel::buildMemberRow( TeamMemberRowView row; row.source_index = source_index; row.node_id = member.node_id; - row.name = member.name; + row.name = member.node_id == 0 + ? member.name + : ::ui::team_presentation::shortTeamMemberLabel(member.node_id); row.online = ::ui::team_presence::isTeamMemberOnline(now_s_, member.last_seen_s); row.leader = member.leader; diff --git a/modules/ui_shared/tests/test_team_map_overlay_source.cpp b/modules/ui_shared/tests/test_team_map_overlay_source.cpp index e76f10a8..41f11a48 100644 --- a/modules/ui_shared/tests/test_team_map_overlay_source.cpp +++ b/modules/ui_shared/tests/test_team_map_overlay_source.cpp @@ -66,9 +66,10 @@ int main() const std::size_t count = source.latestTeamPoints(points, 4); assert(count == 2); assert(points[0].node_id == 0xCAFE); - assert(std::strcmp(points[0].label, "Ada") == 0); + assert(std::strcmp(points[0].label, "CAFE") == 0); assert(points[0].valid); assert(points[1].node_id == 0xBEEF); + assert(points[1].label == nullptr); assert(!points[1].valid); ui::presentation_sources::TeamMapLocation locations[4]{}; diff --git a/modules/ui_shared/tests/test_team_page_event_effect_sink.cpp b/modules/ui_shared/tests/test_team_page_event_effect_sink.cpp index 346b1bac..554915f9 100644 --- a/modules/ui_shared/tests/test_team_page_event_effect_sink.cpp +++ b/modules/ui_shared/tests/test_team_page_event_effect_sink.cpp @@ -16,26 +16,11 @@ team::TeamId testTeamId() return id; } -class FakeNames final : public team::ui::ITeamPageMemberNameResolver -{ - public: - std::string resolveMemberName(uint32_t node_id) const override - { - if (node_id == 0x22222222) - { - return "Ada"; - } - return "Unknown"; - } -}; - team::ui::TeamPageEventReducer makeReducer() { - static FakeNames names; team::ui::TeamPageEventContext context; context.now_s = 1000; context.self_node_id = 0x11111111; - context.names = &names; return team::ui::TeamPageEventReducer(context); } @@ -263,7 +248,6 @@ void testStatusEffectsConfirmKeyDistAndAppendEpoch() FakeKeyEventWriter writer; team::ui::TeamPageKeyEventLog log(writer, 900); team::ui::TeamPageRuntimePort runtime(nullptr, nullptr, nullptr); - FakeNames names; const auto result = team::ui::TeamPageEventEffectSink().applyEffects( state, @@ -273,8 +257,7 @@ void testStatusEffectsConfirmKeyDistAndAppendEpoch() runtime, log, deferred, - notifier, - names); + notifier); assert(result.confirmed_keydist); assert(result.appended_epoch_rotated); @@ -303,7 +286,6 @@ void testKeyDistEffectsSaveApplyKeysAndForwardNavigationRequests() FakeController controller; FakeKeyStore key_store; team::ui::TeamPageRuntimePort runtime(&controller, nullptr, &key_store); - FakeNames names; const auto result = team::ui::TeamPageEventEffectSink().applyEffects( state, @@ -313,8 +295,7 @@ void testKeyDistEffectsSaveApplyKeysAndForwardNavigationRequests() runtime, log, deferred, - notifier, - names); + notifier); assert(result.saved_keys); assert(result.applied_keys); @@ -350,7 +331,6 @@ void testPairingEffectsAppendAcceptedMemberSendStatusAndNotify() team::ui::TeamPageKeyEventLog log(writer, 900); FakeController controller; team::ui::TeamPageRuntimePort runtime(&controller, nullptr, nullptr); - FakeNames names; const auto result = team::ui::TeamPageEventEffectSink().applyEffects( state, @@ -360,8 +340,7 @@ void testPairingEffectsAppendAcceptedMemberSendStatusAndNotify() runtime, log, deferred, - notifier, - names); + notifier); assert(result.appended_member_accepted); assert(result.sent_status); @@ -381,7 +360,7 @@ void testPairingEffectsAppendAcceptedMemberSendStatusAndNotify() assert(deferred.scheduled[0].first == 1); assert(deferred.scheduled[0].second == 2); assert(notifier.messages.size() == 2); - assert(notifier.messages[0] == "Paired: Ada"); + assert(notifier.messages[0] == "Paired: 2222"); assert(notifier.messages[1] == "Paired successfully"); } @@ -399,7 +378,6 @@ void testStatusSendFailuresAreTranslatedToNotifier() controller.status_ok = false; controller.status_plain_ok = false; team::ui::TeamPageRuntimePort runtime(&controller, nullptr, nullptr); - FakeNames names; const auto result = team::ui::TeamPageEventEffectSink().applyEffects( state, @@ -409,8 +387,7 @@ void testStatusSendFailuresAreTranslatedToNotifier() runtime, log, deferred, - notifier, - names); + notifier); assert(!result.sent_status); assert(!result.sent_status_plain); diff --git a/modules/ui_shared/tests/test_team_page_event_reducer.cpp b/modules/ui_shared/tests/test_team_page_event_reducer.cpp index 8e0d46ed..dc14ad97 100644 --- a/modules/ui_shared/tests/test_team_page_event_reducer.cpp +++ b/modules/ui_shared/tests/test_team_page_event_reducer.cpp @@ -5,23 +5,6 @@ namespace { -class FakeNames final : public team::ui::ITeamPageMemberNameResolver -{ - public: - std::string resolveMemberName(uint32_t node_id) const override - { - if (node_id == 0x22222222) - { - return "Ada"; - } - if (node_id == 0x33333333) - { - return "Ben"; - } - return ""; - } -}; - team::TeamId testTeamId() { team::TeamId id{}; @@ -32,11 +15,9 @@ team::TeamId testTeamId() team::ui::TeamPageEventReducer makeReducer() { - static FakeNames names; team::ui::TeamPageEventContext context; context.now_s = 1000; context.self_node_id = 0x11111111; - context.names = &names; return team::ui::TeamPageEventReducer(context); } @@ -81,7 +62,7 @@ void testStatusRostersPreservePresenceAndLeader() assert(state.members[0].name == "You"); assert(state.members[0].leader); assert(state.members[1].node_id == 0x22222222); - assert(state.members[1].name == "Ada"); + assert(state.members[1].name == "2222"); assert(state.members[1].last_seen_s == 990); } @@ -118,7 +99,7 @@ void testActivityTouchesSenderAndConfirmsKeys() assert(effects.keydist_confirmed); assert(effects.keydist_key_id == 7); assert(state.members.size() == 1); - assert(state.members[0].name == "Ada"); + assert(state.members[0].name == "2222"); assert(state.last_update_s == 990); } @@ -192,7 +173,7 @@ void testTransferLeaderUpdatesRoster() assert(state.members.size() == 2); assert(!state.members[0].leader); assert(state.members[1].node_id == 0x33333333); - assert(state.members[1].name == "Ben"); + assert(state.members[1].name == "3333"); assert(state.members[1].leader); } diff --git a/modules/ui_shared/tests/test_team_page_read_model.cpp b/modules/ui_shared/tests/test_team_page_read_model.cpp index e01ca46b..07753f9a 100644 --- a/modules/ui_shared/tests/test_team_page_read_model.cpp +++ b/modules/ui_shared/tests/test_team_page_read_model.cpp @@ -79,11 +79,13 @@ void testRowsDoNotMutatePresence() assert(rows.size() == 3); assert(rows[0].source_index == 0); - assert(rows[0].name == "Ada"); + assert(rows[0].name == "1111"); assert(rows[0].online); assert(rows[0].leader); assert(rows[1].source_index == 1); + assert(rows[1].name == "2222"); assert(!rows[1].online); + assert(rows[2].name == "3333"); assert(input.members[0].online == false); } @@ -95,7 +97,7 @@ void testMemberDetailProjection() const auto detail = model.buildSelectedMember(input); assert(detail.valid); - assert(detail.member.name == "Ben"); + assert(detail.member.name == "2222"); assert(!detail.member.online); assert(detail.last_seen.kind == team::ui::TeamRelativeTimeKind::MinutesAgo); assert(detail.last_seen.value == 6);