Poc: Add/Remove roster groups
This commit is contained in:
parent
441cf7c902
commit
206fd1c8da
|
@ -8,6 +8,7 @@ import android.util.Log;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
@ -18,6 +19,7 @@ import androidx.fragment.app.Fragment;
|
|||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.ViewModelStoreOwner;
|
||||
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.chip.ChipGroup;
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
||||
|
||||
|
@ -26,10 +28,11 @@ import org.mercury_im.messenger.R;
|
|||
import org.mercury_im.messenger.ui.chat.ChatActivity;
|
||||
import org.mercury_im.messenger.util.ColorUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
|
@ -59,6 +62,9 @@ public class ContactDetailFragment extends Fragment {
|
|||
@BindView(R.id.fab)
|
||||
ExtendedFloatingActionButton fab;
|
||||
|
||||
@BindView(R.id.button_add_to_group)
|
||||
Button button;
|
||||
|
||||
private ContactDetailViewModel viewModel;
|
||||
|
||||
@Nullable
|
||||
|
@ -98,6 +104,15 @@ public class ContactDetailFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
viewModel.addContactToRosterGroup().subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe();
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -132,5 +147,24 @@ public class ContactDetailFragment extends Fragment {
|
|||
viewModel.getContactAddress().observe(this, address -> contactAddress.setText(address));
|
||||
viewModel.getContactPresenceStatus().observe(this, presenceText -> contactPresence.setText(presenceText));
|
||||
viewModel.getContactAccountAddress().observe(this, address -> contactAccount.setText(address));
|
||||
viewModel.getContactGroups().observe(this, this::setRosterGroups);
|
||||
}
|
||||
|
||||
private void setRosterGroups(List<String> groups) {
|
||||
contactGroups.removeAllViews();
|
||||
for (String group : groups) {
|
||||
Chip chip = new Chip(contactGroups.getContext());
|
||||
chip.setText(group);
|
||||
chip.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
viewModel.removeContactFromRosterGroup(group)
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
contactGroups.addView(chip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import org.jivesoftware.smack.packet.Presence;
|
|||
import org.jivesoftware.smack.roster.PresenceEventListener;
|
||||
import org.jivesoftware.smack.roster.Roster;
|
||||
import org.jivesoftware.smack.roster.RosterEntry;
|
||||
import org.jivesoftware.smack.roster.RosterGroup;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
|
@ -23,10 +25,15 @@ import org.mercury_im.messenger.entity.contact.Peer;
|
|||
import org.mercury_im.messenger.ui.avatar.AvatarDrawable;
|
||||
import org.mercury_im.messenger.util.CombinedPresenceListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
@ -46,6 +53,7 @@ public class ContactDetailViewModel extends ViewModel {
|
|||
private MutableLiveData<String> contactPresenceStatus = new MutableLiveData<>("Going down the rabbit hole.");
|
||||
private MutableLiveData<String> contactName = new MutableLiveData<>("Alice Wonderland");
|
||||
private MutableLiveData<String> contactAccountAddress = new MutableLiveData<>("mad@hatter.lit");
|
||||
private MutableLiveData<List<String>> contactGroups = new MutableLiveData<>(Collections.emptyList());
|
||||
|
||||
private Roster roster;
|
||||
|
||||
|
@ -58,6 +66,8 @@ public class ContactDetailViewModel extends ViewModel {
|
|||
|
||||
public void bind(UUID accountId, String peerAddress) {
|
||||
Log.d("MMMMMM", "Bind!");
|
||||
roster = Roster.getInstanceFor(messenger.getConnectionManager().getConnection(accountId).getConnection());
|
||||
roster.addPresenceEventListener(presenceEventListener);
|
||||
contactAddress.setValue(peerAddress);
|
||||
contactAccountId.setValue(accountId);
|
||||
disposable.add(peerRepository.observePeerByAddress(accountId, peerAddress)
|
||||
|
@ -71,12 +81,21 @@ public class ContactDetailViewModel extends ViewModel {
|
|||
contactAccountAddress.setValue(peer.getAccount().getAddress());
|
||||
contactAvatar.setValue(new AvatarDrawable(peer.getDisplayName(), peer.getAddress()));
|
||||
contactName.setValue(peer.getDisplayName());
|
||||
|
||||
RosterEntry entry = roster.getEntry(JidCreate.entityBareFromOrThrowUnchecked(peerAddress));
|
||||
if (entry != null) {
|
||||
List<RosterGroup> groups = entry.getGroups();
|
||||
List<String> groupNames = new ArrayList<>(groups.size());
|
||||
for (RosterGroup g : groups) {
|
||||
groupNames.add(g.getName());
|
||||
}
|
||||
contactGroups.postValue(groupNames);
|
||||
}
|
||||
}));
|
||||
|
||||
roster = Roster.getInstanceFor(messenger.getConnectionManager().getConnection(accountId).getConnection());
|
||||
roster.addPresenceEventListener(presenceEventListener);
|
||||
BareJid jid = JidCreate.entityBareFromOrThrowUnchecked(peerAddress);
|
||||
|
||||
Presence presence = roster.getPresence(JidCreate.entityBareFromOrThrowUnchecked(peerAddress));
|
||||
Presence presence = roster.getPresence(jid);
|
||||
if (presence != null) {
|
||||
contactPresenceMode.postValue(presence.getMode());
|
||||
contactPresenceStatus.postValue(presence.getStatus());
|
||||
|
@ -120,6 +139,10 @@ public class ContactDetailViewModel extends ViewModel {
|
|||
return contactAccountAddress;
|
||||
}
|
||||
|
||||
public LiveData<List<String>> getContactGroups() {
|
||||
return contactGroups;
|
||||
}
|
||||
|
||||
private final PresenceEventListener presenceEventListener = new CombinedPresenceListener() {
|
||||
@Override
|
||||
public void presenceReceived(Jid address, Presence presence) {
|
||||
|
@ -138,4 +161,28 @@ public class ContactDetailViewModel extends ViewModel {
|
|||
entry.setName(newName);
|
||||
}
|
||||
}
|
||||
|
||||
public Completable addContactToRosterGroup() {
|
||||
return Completable.fromAction(() -> doAddContactToRosterGroup());
|
||||
}
|
||||
|
||||
private void doAddContactToRosterGroup() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||
String groupName = "Mercury Seven";
|
||||
RosterGroup group = roster.getGroup(groupName);
|
||||
if (group == null) {
|
||||
group = roster.createGroup(groupName);
|
||||
}
|
||||
BareJid jid = JidCreate.entityBareFromOrThrowUnchecked(getContactAddress().getValue());
|
||||
if (group.contains(jid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RosterEntry entry = roster.getEntry(jid);
|
||||
group.addEntry(entry);
|
||||
}
|
||||
|
||||
public Completable removeContactFromRosterGroup(String group) {
|
||||
return Completable.fromAction(() -> roster.getGroup(group).removeEntry(roster.getEntry(JidCreate.entityBareFromOrThrowUnchecked(getContactAddress().getValue()))));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,12 @@
|
|||
android:text="Dungeons n' Dragons"/>
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_add_to_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Mark Mercury Seven"/>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.mercury_im.messenger.data.model;
|
|||
import org.mercury_im.messenger.data.converter.SubscriptionDirectionConverter;
|
||||
import org.mercury_im.messenger.entity.contact.SubscriptionDirection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.requery.CascadeAction;
|
||||
|
@ -42,6 +43,9 @@ public abstract class AbstractPeerModel implements Persistable {
|
|||
@Convert(SubscriptionDirectionConverter.class)
|
||||
SubscriptionDirection subscriptionDirection;
|
||||
|
||||
@Column
|
||||
List<String> groupNames;
|
||||
|
||||
boolean subscriptionPending;
|
||||
|
||||
boolean subscriptionPreApproved;
|
||||
|
|
|
@ -198,6 +198,9 @@ public class MercuryRosterStore implements RosterStore {
|
|||
}
|
||||
item.setApproved(contactModel.isSubscriptionApproved());
|
||||
item.setSubscriptionPending(contactModel.isSubscriptionPending());
|
||||
for (String groupName : contactModel.getGroupNames()) {
|
||||
item.addGroupName(groupName);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
@ -210,7 +213,7 @@ public class MercuryRosterStore implements RosterStore {
|
|||
}
|
||||
peer.setSubscriptionApproved(item.isApproved());
|
||||
peer.setSubscriptionPending(item.isSubscriptionPending());
|
||||
|
||||
peer.setGroupNames(new ArrayList<>(item.getGroupNames()));
|
||||
return peer;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public class CsiManager implements ClientStateListener {
|
|||
private void tryCsiActive(MercuryConnection connection) {
|
||||
try {
|
||||
ClientStateIndicationManager.active(connection.getConnection());
|
||||
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
||||
} catch (SmackException.NotConnectedException | InterruptedException | IllegalArgumentException e) {
|
||||
LOGGER.log(Level.WARNING, "Sending CSI state 'active' failed.", e);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class CsiManager implements ClientStateListener {
|
|||
private void tryCsiInactive(MercuryConnection connection) {
|
||||
try {
|
||||
ClientStateIndicationManager.inactive(connection.getConnection());
|
||||
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
||||
} catch (SmackException.NotConnectedException | InterruptedException | IllegalArgumentException e) {
|
||||
LOGGER.log(Level.WARNING, "Sending CSI state 'inactive' failed.", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.mercury_im.messenger.entity.contact;
|
|||
|
||||
import org.mercury_im.messenger.entity.Account;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import lombok.Data;
|
||||
|
@ -19,6 +20,7 @@ public class Peer {
|
|||
SubscriptionDirection subscriptionDirection;
|
||||
boolean subscriptionPending;
|
||||
boolean subscriptionApproved;
|
||||
List<String> groupNames;
|
||||
|
||||
public Peer() {
|
||||
this.id = UUID.randomUUID();
|
||||
|
|
Loading…
Reference in New Issue