Fix duplicate contacts on rename
This commit is contained in:
parent
647695b081
commit
6504170d58
|
@ -44,31 +44,30 @@ public class LoginViewModel extends AndroidViewModel {
|
|||
|
||||
public void setUsername(String username) {
|
||||
if (username == null || username.isEmpty()) {
|
||||
this.username = null;
|
||||
usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_field_required)));
|
||||
this.username = null;
|
||||
updateLoginEnabled();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.username = JidCreate.entityBareFrom(username);
|
||||
updateLoginEnabled();
|
||||
} catch (XmppStringprepException e) {
|
||||
usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_invalid_username)));
|
||||
this.username = null;
|
||||
updateLoginEnabled();
|
||||
} else {
|
||||
try {
|
||||
this.username = JidCreate.entityBareFrom(username);
|
||||
} catch (XmppStringprepException e) {
|
||||
this.username = null;
|
||||
usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_invalid_username)));
|
||||
}
|
||||
}
|
||||
updateLoginButtonState();
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
updateLoginEnabled();
|
||||
if (password == null || password.isEmpty()) {
|
||||
this.password = null;
|
||||
passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_field_required)));
|
||||
} else {
|
||||
this.password = password;
|
||||
}
|
||||
updateLoginButtonState();
|
||||
}
|
||||
|
||||
private void updateLoginEnabled() {
|
||||
private void updateLoginButtonState() {
|
||||
loginButtonEnabled.setValue(username != null && !(password == null || password.isEmpty()));
|
||||
}
|
||||
|
||||
|
@ -81,15 +80,19 @@ public class LoginViewModel extends AndroidViewModel {
|
|||
disposable.add(messenger.addAccount()
|
||||
.setAddress(username.asEntityBareJidString())
|
||||
.setPassword(password)
|
||||
.loginAndStoreAccountIfSuccessful()
|
||||
.execute()
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnComplete(() -> loginCompleted.setValue(true))
|
||||
.doOnError(this::handleConnectionError)
|
||||
.doOnComplete(this::signalLoginSuccessful)
|
||||
.doOnError(this::signalLoginError)
|
||||
.subscribe());
|
||||
}
|
||||
|
||||
private void handleConnectionError(Throwable error) {
|
||||
private void signalLoginSuccessful() {
|
||||
loginCompleted.setValue(true);
|
||||
}
|
||||
|
||||
private void signalLoginError(Throwable error) {
|
||||
if (error instanceof SASLErrorException) {
|
||||
passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_incorrect_password)));
|
||||
loginButtonEnabled.setValue(true);
|
||||
|
@ -99,12 +102,6 @@ public class LoginViewModel extends AndroidViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
public LiveData<Error> getPasswordError() {
|
||||
return passwordError;
|
||||
}
|
||||
|
@ -121,6 +118,12 @@ public class LoginViewModel extends AndroidViewModel {
|
|||
return loginButtonEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
public static class Error {
|
||||
|
||||
private String message;
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.requery.Convert;
|
|||
import io.requery.Entity;
|
||||
import io.requery.ForeignKey;
|
||||
import io.requery.Generated;
|
||||
import io.requery.Index;
|
||||
import io.requery.Key;
|
||||
import io.requery.ManyToOne;
|
||||
import io.requery.Persistable;
|
||||
|
@ -19,17 +20,19 @@ import io.requery.Table;
|
|||
import io.requery.converter.UUIDConverter;
|
||||
|
||||
@Entity
|
||||
@Table(name = "contacts")
|
||||
@Table(name = "contacts", uniqueIndexes = "unique_address")
|
||||
public abstract class AbstractPeerModel implements Persistable {
|
||||
|
||||
@Key
|
||||
@Convert(UUIDConverter.class)
|
||||
UUID id;
|
||||
|
||||
@Index("unique_address")
|
||||
@ManyToOne(cascade = CascadeAction.NONE)
|
||||
@ForeignKey(referencedColumn = "id")
|
||||
AccountModel account;
|
||||
|
||||
@Index("unique_address")
|
||||
@Column(nullable = false)
|
||||
String address;
|
||||
|
||||
|
|
|
@ -107,11 +107,11 @@ public class XmppPeerRepository
|
|||
public Single<Peer> getOrCreatePeer(Account account, String address) {
|
||||
return getPeerByAddress(account, address)
|
||||
.switchIfEmpty(Single
|
||||
.just(new IPeer(){
|
||||
{
|
||||
setAccount(account);
|
||||
setAddress(address);
|
||||
}
|
||||
.just(new IPeer())
|
||||
.map(peer -> {
|
||||
peer.setAccount(account);
|
||||
peer.setAddress(address);
|
||||
return peer;
|
||||
})
|
||||
.flatMap(this::insertPeer))
|
||||
.subscribeOn(subscriberScheduler())
|
||||
|
@ -121,6 +121,7 @@ public class XmppPeerRepository
|
|||
@Override
|
||||
public Observable<List<Peer>> observeAllPeers() {
|
||||
return data().select(PeerModel.class)
|
||||
.orderBy(PeerModel.ADDRESS)
|
||||
.get().observableResult()
|
||||
.map(ResultDelegate::toList)
|
||||
.map(peerModels -> {
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.jxmpp.jid.impl.JidCreate;
|
|||
import org.mercury_im.messenger.data.repository.AccountRepository;
|
||||
import org.mercury_im.messenger.data.repository.PeerRepository;
|
||||
import org.mercury_im.messenger.entity.Account;
|
||||
import org.mercury_im.messenger.entity.contact.IPeer;
|
||||
import org.mercury_im.messenger.entity.contact.Peer;
|
||||
import org.mercury_im.messenger.entity.contact.SubscriptionDirection;
|
||||
|
||||
|
@ -80,7 +79,7 @@ public class MercuryRosterStore implements RosterStore {
|
|||
|
||||
@Override
|
||||
public RosterPacket.Item getEntry(Jid bareJid) {
|
||||
return itemMap.get(bareJid);
|
||||
return itemMap.get(bareJid.asUnescapedString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -90,27 +89,30 @@ public class MercuryRosterStore implements RosterStore {
|
|||
|
||||
@Override
|
||||
public boolean addEntry(RosterPacket.Item item, String version) {
|
||||
LOGGER.log(Level.INFO, "Add entry " + item.toXML().toString());
|
||||
// Update database
|
||||
Peer contact = toEntity(item);
|
||||
disposable.add(peerRepository.upsertPeer(contact)
|
||||
.map(p -> {
|
||||
LOGGER.log(Level.INFO, "Unserted Peer for account " + p.getAccount().getId());
|
||||
return p;
|
||||
})
|
||||
writeEntryToDatabase(item);
|
||||
writeRosterVersionToDatabase(version);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void writeEntryToDatabase(RosterPacket.Item item) {
|
||||
disposable.add(peerRepository.getOrCreatePeer(account, item.getJid().asUnescapedString())
|
||||
.map(peer -> toEntity(item, peer))
|
||||
.flatMap(peerRepository::updatePeer)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted contact model " + success + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + contact, error)
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + item.getJid().asUnescapedString(), error)
|
||||
));
|
||||
/*
|
||||
}
|
||||
|
||||
private void writeRosterVersionToDatabase(String version) {
|
||||
/*
|
||||
disposable.add(peerRepository.updateRosterVersion(account, version)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted roster version to " + rosterVersion + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting roster version", error)
|
||||
));
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -119,16 +121,7 @@ public class MercuryRosterStore implements RosterStore {
|
|||
// Update database
|
||||
// TODO: Delete other contacts
|
||||
for (RosterPacket.Item item : items) {
|
||||
Peer model = toEntity(item);
|
||||
disposable.add(peerRepository.upsertPeer(model)
|
||||
.map(p -> {
|
||||
LOGGER.log(Level.INFO, "Unserted Peer for account " + p.getAccount().getId());
|
||||
return p;
|
||||
})
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted contact model " + success + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + model, error)
|
||||
));
|
||||
writeEntryToDatabase(item);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -191,8 +184,7 @@ public class MercuryRosterStore implements RosterStore {
|
|||
return item;
|
||||
}
|
||||
|
||||
public Peer toEntity(RosterPacket.Item item) {
|
||||
Peer peer = new IPeer();
|
||||
public Peer toEntity(RosterPacket.Item item, Peer peer) {
|
||||
peer.setAccount(account);
|
||||
peer.setAddress(item.getJid().asEntityBareJidOrThrow().asEntityBareJidString());
|
||||
peer.setName(item.getName());
|
||||
|
|
|
@ -23,6 +23,13 @@ public class AddAccount {
|
|||
|
||||
private static final Logger LOGGER = Logger.getLogger(AddAccount.class.getName());
|
||||
|
||||
public enum ConnectionResult {
|
||||
success,
|
||||
credential_error,
|
||||
server_error,
|
||||
other_error
|
||||
}
|
||||
|
||||
private Account account;
|
||||
private MercuryConnection connection;
|
||||
|
||||
|
@ -42,22 +49,19 @@ public class AddAccount {
|
|||
return this;
|
||||
}
|
||||
|
||||
public boolean isAddressSet() {
|
||||
return account.getAddress() != null;
|
||||
}
|
||||
|
||||
public AddAccount setPassword(String password) {
|
||||
this.account.setPassword(password);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isPasswordSet() {
|
||||
return account.getPassword() != null;
|
||||
public Completable execute() {
|
||||
return loginAndStoreAccountIfSuccessful();
|
||||
}
|
||||
|
||||
public Completable loginAndStoreAccountIfSuccessful() {
|
||||
return login().andThen(insertEnabledAccountIntoDatabase()).ignoreElement()
|
||||
.andThen(Completable.fromAction(() -> messenger.addConnection(connection)));
|
||||
return logIntoAccount()
|
||||
.andThen(insertEnabledAccountIntoDatabase()).ignoreElement()
|
||||
.andThen(addConnectionToMessenger());
|
||||
}
|
||||
|
||||
private Single<Account> insertEnabledAccountIntoDatabase() {
|
||||
|
@ -66,6 +70,10 @@ public class AddAccount {
|
|||
.map(this::updateAccount);
|
||||
}
|
||||
|
||||
private Completable addConnectionToMessenger() {
|
||||
return Completable.fromAction(() -> messenger.addConnection(connection));
|
||||
}
|
||||
|
||||
private Account updateAccount(Account account) {
|
||||
this.account = account;
|
||||
updateAccountIdInConnection(account);
|
||||
|
@ -78,7 +86,7 @@ public class AddAccount {
|
|||
}
|
||||
}
|
||||
|
||||
private Completable login() {
|
||||
private Completable logIntoAccount() {
|
||||
return Completable.fromAction(
|
||||
() -> {
|
||||
getOrCreateConnection();
|
||||
|
@ -117,11 +125,4 @@ public class AddAccount {
|
|||
((AbstractXMPPConnection) connection.getConnection()).connect().login();
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConnectionResult {
|
||||
success,
|
||||
credential_error,
|
||||
server_error,
|
||||
other_error
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue