Skip to content

feat: track member sending state as part of libsession #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
89 changes: 79 additions & 10 deletions src/groups/meta_group_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<MetaGroupWrapper>{info} {}
Expand Down Expand Up @@ -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<session::config::groups::member> allMembers;
std::vector<Napi::Object> 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<session::config::groups::member> allMembersRemoved;
std::vector<Napi::Object> 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;
});
}

Expand All @@ -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();
});
}

Expand All @@ -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));
});
}

Expand All @@ -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));
});
}

Expand Down
63 changes: 1 addition & 62 deletions src/groups/meta_group_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,68 +18,7 @@ using session::config::NOT_REMOVED;
using session::config::groups::member;
using session::nodeapi::MetaGroup;

template <>
struct toJs_impl<member> {
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<Keys::swarm_auth> {
Expand Down
4 changes: 4 additions & 0 deletions types/groups/groupmembers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ 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
* - INVITE_ACCEPTED: regular member
*
* **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
Expand All @@ -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'
Expand Down
Loading