From c901fb4dd6af1258876c8b496f7dc2c8753f7e3b Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Thu, 19 Dec 2024 15:42:07 +1100 Subject: [PATCH] feat: track member sending state as part of libsession --- libsession-util | 2 +- package.json | 2 +- src/groups/meta_group_wrapper.cpp | 89 +++++++++++++++++++++++++++---- src/groups/meta_group_wrapper.hpp | 63 +--------------------- types/groups/groupmembers.d.ts | 4 ++ 5 files changed, 86 insertions(+), 74 deletions(-) diff --git a/libsession-util b/libsession-util index 43b1c6c..5806b91 160000 --- a/libsession-util +++ b/libsession-util @@ -1 +1 @@ -Subproject commit 43b1c6c341ee8739a8678c631d0713136dbfd05f +Subproject commit 5806b9156b2dca4990dc63baed99c02e20139819 diff --git a/package.json b/package.json index 9db835a..f30caff 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "main": "index.js", "name": "libsession_util_nodejs", "description": "Wrappers for the Session Util Library", - "version": "0.4.8", + "version": "0.4.9", "license": "GPL-3.0", "author": { "name": "Oxen Project", diff --git a/src/groups/meta_group_wrapper.cpp b/src/groups/meta_group_wrapper.cpp index 4f2f49f..117688b 100644 --- a/src/groups/meta_group_wrapper.cpp +++ b/src/groups/meta_group_wrapper.cpp @@ -9,6 +9,68 @@ namespace session::nodeapi { +Napi::Object member_to_js(const Napi::Env& env, const member& info, const member::Status& status) { + auto obj = Napi::Object::New(env); + + obj["pubkeyHex"] = toJs(env, info.session_id); + obj["name"] = toJs(env, info.name); + obj["profilePicture"] = toJs(env, info.profile_picture); + + switch (status) { + // invite statuses + case member::Status::invite_unknown: + obj["memberStatus"] = toJs(env, "INVITE_UNKNOWN"); + break; + case member::Status::invite_not_sent: + obj["memberStatus"] = toJs(env, "INVITE_NOT_SENT"); + break; + case member::Status::invite_sending: + obj["memberStatus"] = toJs(env, "INVITE_SENDING"); + break; + case member::Status::invite_failed: obj["memberStatus"] = toJs(env, "INVITE_FAILED"); break; + case member::Status::invite_sent: obj["memberStatus"] = toJs(env, "INVITE_SENT"); break; + case member::Status::invite_accepted: + obj["memberStatus"] = toJs(env, "INVITE_ACCEPTED"); + break; + + // promotion statuses + case member::Status::promotion_unknown: + obj["memberStatus"] = toJs(env, "PROMOTION_UNKNOWN"); + break; + case member::Status::promotion_not_sent: + obj["memberStatus"] = toJs(env, "PROMOTION_NOT_SENT"); + break; + case member::Status::promotion_sending: + obj["memberStatus"] = toJs(env, "PROMOTION_SENDING"); + break; + case member::Status::promotion_failed: + obj["memberStatus"] = toJs(env, "PROMOTION_FAILED"); + break; + case member::Status::promotion_sent: + obj["memberStatus"] = toJs(env, "PROMOTION_SENT"); + break; + case member::Status::promotion_accepted: + obj["memberStatus"] = toJs(env, "PROMOTION_ACCEPTED"); + break; + + // removed statuses + case member::Status::removed_unknown: + obj["memberStatus"] = toJs(env, "REMOVED_UNKNOWN"); + break; + case member::Status::removed: obj["memberStatus"] = toJs(env, "REMOVED_MEMBER"); break; + case member::Status::removed_including_messages: + obj["memberStatus"] = toJs(env, "REMOVED_MEMBER_AND_MESSAGES"); + break; + + default: throw std::runtime_error{"Invalid member status got as an enum"}; + } + + // we display the "crown" on top of the member's avatar when this field is true + obj["nominatedAdmin"] = toJs(env, info.admin); + + return obj; +}; + MetaGroupWrapper::MetaGroupWrapper(const Napi::CallbackInfo& info) : meta_group{std::move(MetaBaseWrapper::constructGroupWrapper(info, "MetaGroupWrapper"))}, Napi::ObjectWrap{info} {} @@ -388,26 +450,28 @@ Napi::Value MetaGroupWrapper::infoDestroy(const Napi::CallbackInfo& info) { Napi::Value MetaGroupWrapper::memberGetAll(const Napi::CallbackInfo& info) { return wrapResult(info, [&] { - std::vector allMembers; + std::vector allMembersJs; for (auto& member : *this->meta_group->members) { - allMembers.push_back(member); + allMembersJs.push_back( + member_to_js(info.Env(), member, meta_group->members->get_status(member))); } - return allMembers; + return allMembersJs; }); } Napi::Value MetaGroupWrapper::memberGetAllPendingRemovals(const Napi::CallbackInfo& info) { return wrapResult(info, [&] { - std::vector allMembersRemoved; + std::vector allMembersRemovedJs; for (auto& member : *this->meta_group->members) { - auto memberStatus = member.status(); + auto memberStatus = this->meta_group->members->get_status(member); if (memberStatus == member::Status::removed_unknown || memberStatus == member::Status::removed || memberStatus == member::Status::removed_including_messages) { - allMembersRemoved.push_back(member); + allMembersRemovedJs.push_back( + member_to_js(info.Env(), member, meta_group->members->get_status(member))); } } - return allMembersRemoved; + return allMembersRemovedJs; }); } @@ -417,7 +481,11 @@ Napi::Value MetaGroupWrapper::memberGet(const Napi::CallbackInfo& info) { assertIsString(info[0]); auto pubkeyHex = toCppString(info[0], "memberGet"); - return meta_group->members->get(pubkeyHex); + auto existing = meta_group->members->get(pubkeyHex); + + return existing ? member_to_js( + info.Env(), *existing, meta_group->members->get_status(*existing)) + : info.Env().Null(); }); } @@ -427,7 +495,8 @@ Napi::Value MetaGroupWrapper::memberGetOrConstruct(const Napi::CallbackInfo& inf assertIsString(info[0]); auto pubkeyHex = toCppString(info[0], "memberGetOrConstruct"); - return meta_group->members->get_or_construct(pubkeyHex); + auto created = meta_group->members->get_or_construct(pubkeyHex); + return member_to_js(info.Env(), created, meta_group->members->get_status(created)); }); } @@ -439,7 +508,7 @@ Napi::Value MetaGroupWrapper::memberConstructAndSet(const Napi::CallbackInfo& in auto pubkeyHex = toCppString(info[0], "memberConstructAndSet"); auto created = meta_group->members->get_or_construct(pubkeyHex); meta_group->members->set(created); - return created; + return member_to_js(info.Env(), created, meta_group->members->get_status(created)); }); } diff --git a/src/groups/meta_group_wrapper.hpp b/src/groups/meta_group_wrapper.hpp index 07ce9a1..28bb8bf 100644 --- a/src/groups/meta_group_wrapper.hpp +++ b/src/groups/meta_group_wrapper.hpp @@ -18,68 +18,7 @@ using session::config::NOT_REMOVED; using session::config::groups::member; using session::nodeapi::MetaGroup; -template <> -struct toJs_impl { - Napi::Object operator()(const Napi::Env& env, const member& info) { - auto obj = Napi::Object::New(env); - - obj["pubkeyHex"] = toJs(env, info.session_id); - obj["name"] = toJs(env, info.name); - obj["profilePicture"] = toJs(env, info.profile_picture); - - auto status = info.status(); - - switch (status) { - // invite statuses - case member::Status::invite_unknown: - obj["memberStatus"] = toJs(env, "INVITE_UNKNOWN"); - break; - case member::Status::invite_not_sent: - obj["memberStatus"] = toJs(env, "INVITE_NOT_SENT"); - break; - case member::Status::invite_failed: - obj["memberStatus"] = toJs(env, "INVITE_FAILED"); - break; - case member::Status::invite_sent: obj["memberStatus"] = toJs(env, "INVITE_SENT"); break; - case member::Status::invite_accepted: - obj["memberStatus"] = toJs(env, "INVITE_ACCEPTED"); - break; - - // promotion statuses - case member::Status::promotion_unknown: - obj["memberStatus"] = toJs(env, "PROMOTION_UNKNOWN"); - break; - case member::Status::promotion_not_sent: - obj["memberStatus"] = toJs(env, "PROMOTION_NOT_SENT"); - break; - case member::Status::promotion_failed: - obj["memberStatus"] = toJs(env, "PROMOTION_FAILED"); - break; - case member::Status::promotion_sent: - obj["memberStatus"] = toJs(env, "PROMOTION_SENT"); - break; - case member::Status::promotion_accepted: - obj["memberStatus"] = toJs(env, "PROMOTION_ACCEPTED"); - break; - - // removed statuses - case member::Status::removed_unknown: - obj["memberStatus"] = toJs(env, "REMOVED_UNKNOWN"); - break; - case member::Status::removed: obj["memberStatus"] = toJs(env, "REMOVED_MEMBER"); break; - case member::Status::removed_including_messages: - obj["memberStatus"] = toJs(env, "REMOVED_MEMBER_AND_MESSAGES"); - break; - - default: throw std::runtime_error{"Invalid member status got as an enum"}; - } - - // we display the "crown" on top of the member's avatar when this field is true - obj["nominatedAdmin"] = toJs(env, info.admin); - - return obj; - } -}; +Napi::Object member_to_js(const Napi::Env& env, const member& info, const member::Status& status); template <> struct toJs_impl { diff --git a/types/groups/groupmembers.d.ts b/types/groups/groupmembers.d.ts index 9de3dcb..22fbbb5 100644 --- a/types/groups/groupmembers.d.ts +++ b/types/groups/groupmembers.d.ts @@ -17,6 +17,7 @@ declare module 'libsession_util_nodejs' { * * **Invite statuses** * - INVITE_UNKNOWN: fallback invite case + * - INVITE_SENDING : when we are actively sending the invite (not synced) * - INVITE_NOT_SENT: as soon as we've scheduled that member to be invited, but before we've tried sending the invite message * - INVITE_FAILED: we know the invite failed to be sent to the member * - INVITE_SENT: we know the invite has been sent to the member @@ -24,6 +25,7 @@ declare module 'libsession_util_nodejs' { * * **Promotion statuses** * - PROMOTION_UNKNOWN: promotion fallback case + * - PROMOTION_SENDING : when we are actively sending the promotion (not synced) * - PROMOTION_NOT_SENT: as soon as we've scheduled that guy to be an admin, but before we've tried sending the promotion message * - PROMOTION_FAILED: we know the promotion failed to be sent to the member * - PROMOTION_SENT: we know the promotion message was sent to the member @@ -36,11 +38,13 @@ declare module 'libsession_util_nodejs' { */ type MemberStateGroupV2 = | 'INVITE_UNKNOWN' + | 'INVITE_SENDING' | 'INVITE_NOT_SENT' | 'INVITE_FAILED' | 'INVITE_SENT' | 'INVITE_ACCEPTED' | 'PROMOTION_UNKNOWN' + | 'PROMOTION_SENDING' | 'PROMOTION_NOT_SENT' | 'PROMOTION_FAILED' | 'PROMOTION_SENT'