Closed valeriansaliou closed 7 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.
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.
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.
Thanks, it is implemented.
Could I receive the contactChanged
event when adding/removing item to roster?
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?
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.
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.
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.
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>
}
Excellent! I’ll apply all changes this weekend.
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
.
Yes, it would definitely make sense to rename using this wording (userInfoChanged
sounds good), which is definitely clearer.
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.
Could I get the JID in PresenceSubRequest
as I'd like to show the user avatar?
It's been implemented, thanks!
We would need the two following methods, in the same style as
addContact
:removeContact
blockContact
/unblockContact
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).