public void offerFile(ListeningFuture<LocalFileItem> future) { // TODO: Change this to show event immediately & update as status changes. future.addFutureListener( new EventListener<FutureEvent<LocalFileItem>>() { @SwingEDTEvent @Override public void handleEvent(FutureEvent<LocalFileItem> event) { if (event.getResult() != null) { FileMetaData metadata = event.getResult().toMetadata(); boolean sentFileOffer = false; Friend friend = chatFriend.getFriend(); // do not send file offer if user not signed in. if (!friend.isSignedIn()) { String errorMsg = I18n.tr("File offer not sent because friend signed off."); Message msg = new MessageFileOfferImpl( I18n.tr("me"), friendId, Message.Type.SENT, metadata, null); messageBroadcaster.broadcast(new ChatMessageEvent(new ErrorMessage(errorMsg, msg))); return; } // if active presence exists, send file offer to it, // otherwise broadcast to every presence with FileOfferFeature.ID feature FriendPresence activePresence = friend.getActivePresence(); if ((activePresence != null) && activePresence.hasFeatures(FileOfferFeature.ID)) { sentFileOffer = performFileOffer(metadata, activePresence); } else { for (FriendPresence presence : friend.getPresences().values()) { sentFileOffer |= performFileOffer(metadata, presence); } } if (sentFileOffer) { messageBroadcaster.broadcast( new ChatMessageEvent( new MessageFileOfferImpl( I18n.tr("me"), friendId, Message.Type.SENT, metadata, null))); } else { // TODO: handle file offer sending failures (consider using ErrorMessage) } } } private boolean performFileOffer(FileMetaData metadata, FriendPresence presence) { Feature fileOfferFeature = presence.getFeature(FileOfferFeature.ID); boolean fileOfferSent = false; if (fileOfferFeature != null) { try { writer.setChatState(ChatState.active); FeatureTransport<FileMetaData> fileOfferer = presence.getTransport(FileOfferFeature.class); fileOfferer.sendFeature(presence, metadata); fileOfferSent = true; } catch (FriendException e) { LOG.debug("File offer failed", e); } } return fileOfferSent; } }); }