prose-im / prose-core-client

Prose core XMPP client manager & protocols.
https://prose.org
Mozilla Public License 2.0
20 stars 3 forks source link

Add contact management methods #45

Closed valeriansaliou closed 7 months ago

valeriansaliou commented 8 months ago

We would need the two following methods, in the same style as addContact:

The former would simply pull out a contact from the roster, the second would add or remove the JID from privacy lists (I would also need a way to know if a given JID is blocked so that I can choose which button to show to the user, ie block or unblock).

nesium commented 8 months ago

Out of curiosity: In which part of the app would you want to call removeContact, since we don't really let the user manage a roster?

Personally I'd prefer to have only to deal with entries in the sidebar and have everything else handled for me. Or in other words: Let's shield the user from the complexities of the XMPP protocol where possible.

But I'm sure I'm missing some things, especially in terms of federation.

valeriansaliou commented 8 months ago

addContact and removeContact are only relevant to me when the target JID domain does not match ours, that is, when the target JID is outside of our workspace. I already implemented addContact, which is why I'd need its reverse.

nesium commented 8 months ago

I have added a method Client::removeContact which you can use already. Although I have yet to update theContactsRepository so that remote changes to the roster are observed and cached accordingly.

valeriansaliou commented 8 months ago

Thanks, it is implemented.

Could I receive the contactChanged event when adding/removing item to roster?

nesium commented 8 months ago

Can do. Or would a rosterChanged event be better, especially in the removed case?

Also should we add contact request handling now too? Like having a list of contact requests that need to be approved?

valeriansaliou commented 8 months ago

rosterChanged would do yes! I'll then stop reloading roster on contactsChanged (although what should I do w/ this event now?)

On the contact request handling, definitely! I think if I can load up from the core library a list of pending invitations that'll do, and be notified when this list changes, but that means that the library should stack all presence subscribes into some sort of storage, which can be loaded on demand.

nesium commented 8 months ago

Quick question @valeriansaliou: Do we still need Contact.group which could be favorite, team or other? I believe that if we'd still need this team and other would suffice since entries in the sidebar have their state saved differently.

Are you planning to use this somewhere? If not, I'd like to get rid of the group concept for contacts which otherwise would add a little more complexity to the current changes.

valeriansaliou commented 8 months ago

We still need to distinguish the Team roster that's server-managed for you, and the Other roster that's your custom external contacts roster. You can remove the Favorite one.

nesium commented 8 months ago

Here's the new TypeScript API…

export enum PresenceSubscription {
  /// We have requested to subscribe to the contact's presence, but they haven't approved yet.
  Requested = 0,

  /// Both we and the contact are subscribed to each other's presence.
  Mutual = 1,

  /// The contact is subscribed to our presence, so they can see our status.
  TheyFollow = 2,

  /// We are subscribed to the contact's presence, so we can see their status.
  WeFollow = 3,

  /// There is no presence subscription between us and the contact.
  None = 4,
}

export class PresenceSubRequest {
  readonly id: PresenceSubRequestId;
  readonly name: string;
}

export enum Group {
  // Favorite is gone
  Team = 0,
  Other = 1,
}

export class Contact {
  // …

  readonly presenceSubscription: PresenceSubscription;
}

export interface ProseClientDelegate {
  // …

  /// The contact list has changed.
  contactListChanged(client: ProseClient): void

  /// The list of presence subscription requests has changed.
  presenceSubscriptionRequestsChanged(client: ProseClient): void

  /// The block list has changed.
  blockListChanged(client: ProseClient): void
}

export class ProseClient {
  // …

  /// Adds a contact to the roster and sends a presence subscription request.
  addContact(jid: JID): Promise<void>
  /// Removes a contact from the roster
  removeContact(jid: JID): Promise<void>
  loadContacts(): Promise<Contact[]>
  /**
   * Requests a presence subscription from `jid`. Note that happens automatically when you
   * call `add_contact`. This method can be useful though when our user needs to re-request
   * the presence subscription in case the contact hasn't reacted in a while.
   */
  requestPresenceSubscription(jid: JID): Promise<void>

  /// Loads pending presence subscription requests.
  loadPresenceSubscriptionRequests(): Promise<PresenceSubRequest[]>

  /// Approves the presence subscription request identified by `id`.
  approvePresenceSubscriptionRequest(id: PresenceSubRequestId): Promise<void>

  /// Denies the presence subscription request identified by `id`.
  denyPresenceSubscriptionRequest(id: PresenceSubRequestId): Promise<void>

  /// Returns the list of blocked users.
  loadBlockList(): Promise<UserBasicInfo[]>

  /// Blocks the user identified by `jid`.
  blockUser(jid: JID): Promise<void>

  /// Unblocks the user identified by `jid`.
  unblockUser(jid: JID): Promise<void>

  /// Removes all users from the block list.
  clearBlockList(): Promise<void>
}
valeriansaliou commented 8 months ago

Excellent! I’ll apply all changes this weekend.

nesium commented 8 months ago

Oh, and regarding your question what contactChanged is for then: I was thinking when you show a detail view for another user and want to be notified about changes. Although it should probably be named userInfoChanged or userDetailsChanged so that it doesn't dilute the concept of a Contact and ContactList.

valeriansaliou commented 8 months ago

Yes, it would definitely make sense to rename using this wording (userInfoChanged sounds good), which is definitely clearer.

valeriansaliou commented 8 months ago

Implemented roster-related changes + block lists in:

Working well, thank you Marc. Will implement presence subscriptions accept/deny and list later on, as it'll go in Spotlight > People & channels.

valeriansaliou commented 8 months ago

Could I get the JID in PresenceSubRequest as I'd like to show the user avatar?

valeriansaliou commented 8 months ago

It's been implemented, thanks!