/** * Becomes invisible. * * @return The async result. */ public AsyncResult<Void> becomeInvisible() { return xmppSession.query(IQ.set(InvisibleCommand.INVISIBLE)).thenRun(() -> { synchronized (InvisibilityManager.this) { invisible = true; } }); }
/** * Becomes visible. * * @return The async result. */ public AsyncResult<Void> becomeVisible() { return xmppSession.query(IQ.set(InvisibleCommand.VISIBLE)).thenRun(() -> { synchronized (InvisibilityManager.this) { invisible = false; } }); }
/** * Removes a contact group. If the group has sub groups, all sub groups are removed as well. * All contacts in this group and all sub groups are moved to the parent group (if present) or to no group at all. * * @param contactGroup The contact group. * @return The async result. */ public final AsyncResult<Void> removeContactGroup(ContactGroup contactGroup) { Collection<Contact> allContacts = collectAllContactsInGroup(contactGroup); CompletableFuture<?>[] completableFutures; if (contactGroup.getParentGroup() != null) { completableFutures = allContacts.stream() .map(contact -> updateContact(contact.withGroups(contactGroup.getParentGroup().getFullName())).thenRun(() -> { }).toCompletableFuture()) .toArray(CompletableFuture<?>[]::new); } else { completableFutures = allContacts.stream() .map(contact -> updateContact(contact.withoutGroups()).thenRun(() -> { }).toCompletableFuture()) .toArray(CompletableFuture<?>[]::new); } return new AsyncResult<>(CompletableFuture.allOf(completableFutures)); }
/** * Adds a contact to the roster and optionally also sends a subscription request to it. * * @param contact The contact. * @param requestSubscription If true, the contact is also sent a subscription request. * @param status The optional status text, which is sent together with a subscription request. May be null. * @return The async result. */ public final AsyncResult<Void> addContact(Contact contact, boolean requestSubscription, String status) { Objects.requireNonNull(contact, "contact must not be null."); AsyncResult<IQ> query = xmppSession.query(IQ.set(new Roster(contact))); return query.thenRun(() -> { if (requestSubscription) { xmppSession.getManager(PresenceManager.class).requestSubscription(contact.getJid(), status); } }); }
/** * Publishes an avatar to your VCard. * * @param imageData The avatar image data, which must be in PNG format. {@code null} resets the avatar. * @return The async result. * @see <a href="https://xmpp.org/extensions/xep-0153.html#publish">3.1 User Publishes Avatar</a> */ public final AsyncResult<Void> publishAvatar(byte[] imageData) { String hash = imageData != null ? XmppUtils.hash(imageData) : null; AvatarMetadata.Info info = imageData != null ? new AvatarMetadata.Info(imageData.length, hash, hash) : null; // Try publishing to vCard first. If this fails, don't immediately throw an exception, but try PEP first. return publishToVCard(imageData, null, hash) .whenComplete((result, e) -> { if (e != null) { logger.warning("Failed to publish avatar to vCard."); } }) .thenCompose((aVoid) -> publishToPersonalEventingService(imageData, hash, info)) .thenRun(() -> { }); }
/** * Saves or updates a vCard. * * @param vCard The vCard. * @return The async result. */ public AsyncResult<Void> setVCard(VCard vCard) { // Update the vCard AsyncResult<IQ> query = xmppSession.query(IQ.set(vCard)); return query.thenRun(() -> { // Then inform about the update by sending a presence. The avatar manager will add the update extension. AvatarManager avatarManager = xmppSession.getManager(AvatarManager.class); if (isEnabled() && avatarManager.isEnabled()) { Presence presence = xmppSession.getManager(PresenceManager.class).getLastSentPresence(); if (presence == null) { presence = new Presence(); } presence.getExtensions().clear(); xmppSession.send(presence); } }); } }