Skip to content
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

Integrate deleted users into the getUsers response #6198

Merged
merged 4 commits into from
Aug 5, 2024
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
33 changes: 1 addition & 32 deletions frontend/openchat-agent/src/services/community/candid/idl.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,56 +58,25 @@ export const idlFactory = ({ IDL }) => {
'added_by_name' : IDL.Text,
'added_by_display_name' : IDL.Opt(IDL.Text),
});
const ICRC2_TransferFromError = IDL.Variant({
'GenericError' : IDL.Record({
'message' : IDL.Text,
'error_code' : IDL.Nat,
}),
'TemporarilyUnavailable' : IDL.Null,
'InsufficientAllowance' : IDL.Record({ 'allowance' : IDL.Nat }),
'BadBurn' : IDL.Record({ 'min_burn_amount' : IDL.Nat }),
'Duplicate' : IDL.Record({ 'duplicate_of' : IDL.Nat }),
'BadFee' : IDL.Record({ 'expected_fee' : IDL.Nat }),
'CreatedInFuture' : IDL.Record({ 'ledger_time' : IDL.Nat64 }),
'TooOld' : IDL.Null,
'InsufficientFunds' : IDL.Record({ 'balance' : IDL.Nat }),
});
const GateCheckFailedReason = IDL.Variant({
'NotLifetimeDiamondMember' : IDL.Null,
'NotDiamondMember' : IDL.Null,
'PaymentFailed' : ICRC2_TransferFromError,
'InsufficientBalance' : IDL.Nat,
'NoSnsNeuronsFound' : IDL.Null,
'NoSnsNeuronsWithRequiredDissolveDelayFound' : IDL.Null,
'Locked' : IDL.Null,
'NoUniquePersonProof' : IDL.Null,
'FailedVerifiedCredentialCheck' : IDL.Text,
'NoSnsNeuronsWithRequiredStakeFound' : IDL.Null,
});
const UserFailedGateCheck = IDL.Record({
'user_id' : UserId,
'reason' : GateCheckFailedReason,
});
const UserFailedError = IDL.Record({
'user_id' : UserId,
'error' : IDL.Text,
});
const AddMembersToChannelFailed = IDL.Record({
'users_limit_reached' : IDL.Vec(UserId),
'users_failed_gate_check' : IDL.Vec(UserFailedGateCheck),
'users_already_in_channel' : IDL.Vec(UserId),
'users_failed_with_error' : IDL.Vec(UserFailedError),
});
const AddMembersToChannelPartialSuccess = IDL.Record({
'users_limit_reached' : IDL.Vec(UserId),
'users_failed_gate_check' : IDL.Vec(UserFailedGateCheck),
'users_already_in_channel' : IDL.Vec(UserId),
'users_failed_with_error' : IDL.Vec(UserFailedError),
'users_added' : IDL.Vec(UserId),
});
const AddMembersToChannelResponse = IDL.Variant({
'Failed' : AddMembersToChannelFailed,
'UserNotInChannel' : IDL.Null,
'CommunityPublic' : IDL.Null,
'PartialSuccess' : AddMembersToChannelPartialSuccess,
'ChannelNotFound' : IDL.Null,
'UserLimitReached' : IDL.Nat32,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down Expand Up @@ -119,13 +120,11 @@ export interface AddMembersToChannelArgs {
}
export interface AddMembersToChannelFailed {
'users_limit_reached' : Array<UserId>,
'users_failed_gate_check' : Array<UserFailedGateCheck>,
'users_already_in_channel' : Array<UserId>,
'users_failed_with_error' : Array<UserFailedError>,
}
export interface AddMembersToChannelPartialSuccess {
'users_limit_reached' : Array<UserId>,
'users_failed_gate_check' : Array<UserFailedGateCheck>,
'users_already_in_channel' : Array<UserId>,
'users_failed_with_error' : Array<UserFailedError>,
'users_added' : Array<UserId>,
Expand All @@ -134,6 +133,7 @@ export type AddMembersToChannelResponse = {
'Failed' : AddMembersToChannelFailed
} |
{ 'UserNotInChannel' : null } |
{ 'CommunityPublic' : null } |
{ 'PartialSuccess' : AddMembersToChannelPartialSuccess } |
{ 'ChannelNotFound' : null } |
{ 'UserLimitReached' : number } |
Expand Down Expand Up @@ -2355,10 +2355,6 @@ export interface UpdatedRules {
}
export interface User { 'username' : string, 'user_id' : UserId }
export interface UserFailedError { 'user_id' : UserId, 'error' : string }
export interface UserFailedGateCheck {
'user_id' : UserId,
'reason' : GateCheckFailedReason,
}
export interface UserGroup {
'members' : number,
'name' : string,
Expand Down
15 changes: 3 additions & 12 deletions frontend/openchat-agent/src/services/community/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import type {
UpdatedEvent,
UpdateUserGroupResponse,
UserFailedError,
UserFailedGateCheck,
UserGroupDetails,
} from "openchat-shared";
import { CommonResponses, UnsupportedValueError } from "openchat-shared";
Expand All @@ -54,7 +53,6 @@ import type {
ApiOptionalCommunityPermissions,
ApiAddMembersToChannelFailed,
ApiAddMembersToChannelPartialSuccess,
ApiUserFailedGateCheck,
ApiUserFailedError,
ApiMessageMatch,
ApiCommunityCanisterCommunitySummaryUpdates,
Expand Down Expand Up @@ -83,7 +81,6 @@ import {
communityChannelSummary,
communityPermissions,
communitySummary,
gateCheckFailedReason,
groupPermissions,
groupSubtype,
memberRole,
Expand Down Expand Up @@ -136,6 +133,9 @@ export function addMembersToChannelResponse(
if ("InternalError" in candid) {
return CommonResponses.internalError();
}
if ("CommunityPublic" in candid) {
return CommonResponses.communityPublic();
}
throw new UnsupportedValueError(
"Unexpected ApiAddMembersToChannelResponse type received",
candid,
Expand All @@ -147,7 +147,6 @@ function addToChannelFailed(candid: ApiAddMembersToChannelFailed): AddMembersToC
kind: "add_to_channel_failed",
usersLimitReached: candid.users_limit_reached.map((u) => u.toString()),
usersAlreadyInChannel: candid.users_already_in_channel.map((u) => u.toString()),
usersFailedGateCheck: candid.users_failed_gate_check.map(userFailedGateCheck),
usersFailedWithError: candid.users_failed_with_error.map(userFailedWithError),
};
}
Expand All @@ -159,21 +158,13 @@ function userFailedWithError(candid: ApiUserFailedError): UserFailedError {
};
}

function userFailedGateCheck(candid: ApiUserFailedGateCheck): UserFailedGateCheck {
return {
userId: candid.user_id.toString(),
reason: gateCheckFailedReason(candid.reason),
};
}

function addToChannelPartialSuccess(
candid: ApiAddMembersToChannelPartialSuccess,
): AddMembersToChannelResponse {
return {
kind: "add_to_channel_partial_success",
usersLimitReached: candid.users_limit_reached.map((u) => u.toString()),
usersAlreadyInChannel: candid.users_already_in_channel.map((u) => u.toString()),
usersFailedGateCheck: candid.users_failed_gate_check.map(userFailedGateCheck),
usersFailedWithError: candid.users_failed_with_error.map(userFailedWithError),
usersAdded: candid.users_added.map((u) => u.toString()),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
1 change: 1 addition & 0 deletions frontend/openchat-agent/src/services/user/candid/idl.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export const idlFactory = ({ IDL }) => {
'StartedCall' : IDL.Null,
'ChosenAsGroupOwner' : IDL.Null,
'TippedMessage' : IDL.Null,
'Streak365' : IDL.Null,
'SentGiphy' : IDL.Null,
'SetCommunityAccessGate' : IDL.Null,
'Streak14' : IDL.Null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down
3 changes: 3 additions & 0 deletions frontend/openchat-agent/src/services/user/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@ export function achievementType(candid: ApiAchievement): Achievement {
if ("Streak7" in candid) {
return "streak_7";
}
if ("Streak365" in candid) {
return "streak_365";
}
if ("UpgradedToGoldDiamond" in candid) {
return "upgrade_to_gold_diamond";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ export const idlFactory = ({ IDL }) => {
});
const UsersResponse = IDL.Variant({
'Success' : IDL.Record({
'deleted' : IDL.Vec(UserId),
'timestamp' : TimestampMillis,
'users' : IDL.Vec(UserSummaryV2),
'current_user' : IDL.Opt(CurrentUserSummary),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Achievement = { 'AppointedGroupModerator' : null } |
{ 'StartedCall' : null } |
{ 'ChosenAsGroupOwner' : null } |
{ 'TippedMessage' : null } |
{ 'Streak365' : null } |
{ 'SentGiphy' : null } |
{ 'SetCommunityAccessGate' : null } |
{ 'Streak14' : null } |
Expand Down Expand Up @@ -1859,6 +1860,7 @@ export interface UsersInvited {
}
export type UsersResponse = {
'Success' : {
'deleted' : Array<UserId>,
'timestamp' : TimestampMillis,
'users' : Array<UserSummaryV2>,
'current_user' : [] | [CurrentUserSummary],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export function usersApiResponse(candid: ApiUsersResponse): UsersApiResponse {
return {
serverTimestamp: timestamp,
users: candid.Success.users.map(userSummaryUpdate),
deletedUserIds: new Set(candid.Success.deleted.map((d) => d.toString())),
currentUser: optional(candid.Success.current_user, (u) =>
currentUserSummary(u, timestamp),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ import { apiOptional, apiToken } from "../common/chatMappers";
import type { AgentConfig } from "../../config";
import {
getCachedUsers,
getCachedDeletedUserIds,
getSuspendedUsersSyncedUpTo,
setCachedDeletedUserIds,
setCachedUsers,
setDisplayNameInCache,
setSuspendedUsersSyncedUpTo,
Expand Down Expand Up @@ -144,16 +146,17 @@ export class UserIndexClient extends CandidService {
const allUsers = users.userGroups.flatMap((g) => g.users);

const fromCache = await getCachedUsers(allUsers);
const cachedDeletedUserIds = await getCachedDeletedUserIds();
const suspendedUsersSyncedTo = await getSuspendedUsersSyncedUpTo();

// We throw away all of the updatedSince values passed in and instead use the values from the cache, this
// ensures the cache is always correct and doesn't miss any updates
const args = this.buildGetUsersArgs(allUsers, fromCache, allowStale);

const apiResponse = await this.getUsersFromBackend(args, suspendedUsersSyncedTo);
const args = this.buildGetUsersArgs(allUsers, fromCache, allowStale, cachedDeletedUserIds);

const requestedFromServer = new Set<string>([...args.userGroups.flatMap((g) => g.users)]);

const apiResponse = await this.getUsersFromBackend(args, suspendedUsersSyncedTo);

// We return the fully hydrated users so that it is not possible for the Svelte store to miss any updates
const mergedResponse = this.mergeGetUsersResponse(
chitState,
Expand All @@ -163,6 +166,8 @@ export class UserIndexClient extends CandidService {
fromCache,
);

setCachedDeletedUserIds(apiResponse.deletedUserIds);

setCachedUsers(mergedResponse.users).catch((err) =>
console.error("Failed to save users to the cache", err),
);
Expand All @@ -188,6 +193,7 @@ export class UserIndexClient extends CandidService {
return Promise.resolve({
serverTimestamp: 0n,
users: [],
deletedUserIds: new Set(),
});

const userGroups = users.userGroups.filter((g) => g.users.length > 0);
Expand All @@ -211,6 +217,7 @@ export class UserIndexClient extends CandidService {
users: string[],
fromCache: UserSummary[],
allowStale: boolean,
cachedDeletedUserIds: Set<string>,
): UsersArgs {
const fromCacheGrouped = groupBy(fromCache, (u) => u.updated);
const fromCacheSet = new Set<string>(fromCache.map((u) => u.userId));
Expand All @@ -220,7 +227,9 @@ export class UserIndexClient extends CandidService {
};

// Add the users not found in the cache and ask for all updates
const notFoundInCache = users.filter((u) => !fromCacheSet.has(u));
const notFoundInCache = users.filter(
(u) => !fromCacheSet.has(u) && !cachedDeletedUserIds.has(u),
);
if (notFoundInCache.length > 0) {
args.userGroups.push({
users: notFoundInCache,
Expand All @@ -232,7 +241,9 @@ export class UserIndexClient extends CandidService {
// Add the users found in the cache but only ask for updates since the date they were last updated in the cache
for (const [updatedSince, users] of fromCacheGrouped) {
args.userGroups.push({
users: users.map((u) => u.userId),
users: users
.filter((u) => !cachedDeletedUserIds.has(u.userId))
.map((u) => u.userId),
updatedSince,
});
}
Expand Down Expand Up @@ -312,6 +323,7 @@ export class UserIndexClient extends CandidService {
serverTimestamp: apiResponse.serverTimestamp,
users,
currentUser: apiResponse.currentUser,
deletedUserIds: apiResponse.deletedUserIds,
};
}

Expand Down
Loading
Loading